Leetcode 855. Exam Room

Problem:

 

In an exam room, there are N seats in a single row, numbered 0, 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 class ExamRoom(int N) that exposes two functions: ExamRoom.seat() returning an int representing what seat the student sat in, and ExamRoom.leave(int p) representing that the student in seat number p now leaves the room.  It is guaranteed that any calls to ExamRoom.leave(p) have a student sitting in seat p.

 

Example 1:

Input: ["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]]
Output: [null,0,9,4,2,null,5]
Explanation:
ExamRoom(10) -> null
seat() -> 0, no one is in the room, then the student sits at seat number 0.
seat() -> 9, the student sits at the last seat number 9.
seat() -> 4, the student sits at the last seat number 4.
seat() -> 2, the student sits at the last seat number 2.
leave(4) -> null
seat() -> 5, the student sits at the last seat number 5.

​​​​​​​

Note:

  1. 1 <= N <= 10^9
  2. ExamRoom.seat() and ExamRoom.leave() will be called at most 10^4 times across all test cases.
  3. Calls to ExamRoom.leave(p) are guaranteed to have a student currently sitting in seat number p.

 

Solution:

  为什么要把这道题写进博客,是因为当时做这道题时进入了一个很大的误区。乍一看这道题就是在所有区间中找极值吗,在动态的情况下找一个极值自然而然就会想到优先级队列。然而seat函数写完之后发现,leave函数非常难实现,因为一旦leave一个人,就需要将与其相邻的两个区间融合成一个,而优先级队列这种数据结构我们无法对其进行遍历,只能将所有元素pop出来然后处理,这样以来时间复杂度又变成了O(n)。既然时间复杂度都达到线性了,我们何不简单一点,seat函数直接线性查找,因此,我们用一个set数据结构,对所有产生的区间进行查询,找到合适的位置放下,注意一些细节即可。这道题刚开始做的时候非常容易陷入优先级队列这个陷阱中,所以我把它写入博客警醒一下自己。

Code:

 

 1 class ExamRoom {
 2 public:
 3     ExamRoom(int N) {
 4         this->N = N;
 5     }
 6     
 7     int seat() {
 8         int student = 0;
 9         if(s.size() > 0){
10             int maxLength = *s.begin();
11             auto iter = s.begin();
12             int before = *iter;
13             iter++;
14             while(iter != s.end()){
15                 int length = (*iter-before)/2;
16                 if(length > maxLength){
17                     maxLength = length;
18                     student = before+length;
19                 }
20                 before = *iter;
21                 iter++;
22             }
23             if(N-1-before > maxLength){
24                 maxLength = N-1-before;
25                 student = N-1;
26             }
27         }
28         s.insert(student);
29         return student;
30     }
31     
32     void leave(int p) {
33         s.erase(p);
34     }
35 private:
36     int N;
37     set<int> s;
38 };
39 
40 /**
41  * Your ExamRoom object will be instantiated and called as such:
42  * ExamRoom obj = new ExamRoom(N);
43  * int param_1 = obj.seat();
44  * obj.leave(p);
45  */

 

posted on 2019-01-17 16:55  周浩炜  阅读(255)  评论(0编辑  收藏  举报

导航