Exam Room
Medium
In an exam room, there areN
seats in a single row, numbered0, 1, 2, ..., N-1
.
When a student enters the room, they must sit in the seat that maximizes the distance to the closest person. If there are multiple such seats, they sit in the seat with the lowest number. (Also, if no one is in the room, then the student sits at seat number 0.)
Return a classExamRoom(int N)
that exposes two functions:ExamRoom.seat()
returning anint
representing what seat the student sat in, andExamRoom.leave(int p)
representing that the student in seat numberp
now leaves the room. It is guaranteed that any calls toExamRoom.leave(p)
have a student sitting in seatp
.
Example 1:
Note:
1 <= N <= 10^9
ExamRoom.seat()
andExamRoom.leave()
will be called at most10^4
times across all test cases.Calls to
ExamRoom.leave(p)
are guaranteed to have a student currently sitting in seat numberp
.
Analysis & Solution
以下from:
https://github.com/awangdev/LintCode/blob/master/Java/Exam Room.java
PriorityQueue
Use priority queue to sort by customized class interval{int dist; int x, y;}.
Sort by larger distance and then sort by start index
seat(): pq.poll() to find interval of largest distance. Split and add new intervals back to queue.
leave(x): one seat will be in 2 intervals: remove both from pq, and merge to a new interval.
主方程写出来其实很好写, 就是 split + add interval, 然后 find + delete interval 而已. 最难的是构建data structure
seat()
:O(logn)
,leave()
:O(n)
Trick: 构建虚拟 boundary
如果是开头的seat, 或者是结尾的seat, 比较难handle: 一开始坐在seat=0的时候, 没有interval啊!
Trick就是, 我们自己定义个虚拟的座位
seat=-1
,seat=N
一开始有一个 interval[-1, N] 然后就建立了boundary.
从此以后, 每次split成小interval的时候:
遇到
interval[-1, y]
, distance就是(y - 0)
遇到
interval[x, N]
, distance就是(N - 1 - x)
当然正常的interval dist 就是
(y - x) / 2
distance 中间点
Interval.dist 我们其实做的是 distance的中间点
(y - x) / 2
这里的dist是
距离两边的距离
而不是 x, y 之间的距离. 这里要特别注意.
TreeSet
Reference
*https://github.com/awangdev/LintCode/blob/master/Java/Exam Room.java
Last updated