在考场里,一排有 N
个座位,分别编号为 0, 1, 2, ..., N-1
。
当学生进入考场后,他必须坐在能够使他与离他最近的人之间的距离达到最大化的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 号座位上。)
返回 ExamRoom(int N)
类,它有两个公开的函数:其中,函数 ExamRoom.seat()
会返回一个 int
(整型数据),代表学生坐的位置;函数 ExamRoom.leave(int p)
代表坐在座位 p
上的学生现在离开了考场。请确保每次调用 ExamRoom.leave(p)
时都有学生坐在座位 p
上。
示例:
输入:["ExamRoom","seat","seat","seat","seat","leave","seat"], [[10],[],[],[],[],[4],[]] 输出:[null,0,9,4,2,null,5] 解释: ExamRoom(10) -> null seat() -> 0,没有人在考场里,那么学生坐在 0 号座位上。 seat() -> 9,学生最后坐在 9 号座位上。 seat() -> 4,学生最后坐在 4 号座位上。 seat() -> 2,学生最后坐在 2 号座位上。 leave(4) -> null seat() -> 5,学生最后坐在 5 号座位上。
提示:
1 <= N <= 10^9
- 在所有的测试样例中
ExamRoom.seat()
和ExamRoom.leave()
最多被调用10^4
次。 - 调用
ExamRoom.leave(p)
时需要确保当前有学生坐在座位p
上。
思路:用一个集合来维持有序性,每次找座位时,找到集合中相邻前后两元素的最大差值,然后计算Index。
有两点需要注意的地方:
一.如果最大的元素不是数组最后的N-1,那么需要计算N-1与最右边元素的差值是否大于当前的最大长度,如果大于,那么把index设置为N-1;
二.长度需要优先除二以消除0.5的区别,保证优先选择前面相同的长度的
Code:
class ExamRoom {
public:
int last;
set<int>cur;
ExamRoom(int N) {
last=N-1;
}
int seat() {
if(cur.size()==0){cur.insert(0);return 0;}
set<int>::iterator ite1 = cur.begin();
int pre=*ite1;
int maxlen=pre;
int index=0;
for(;ite1!=cur.end();ite1++)
{
if((*ite1-pre)/2>maxlen){maxlen=(*ite1-pre)/2;index=pre+maxlen;}
pre=*ite1;
}
if((last-pre)>maxlen) index=last;
cur.insert(index);
return index;
}
void leave(int p) {
cur.erase(p);
}
};
/**
* Your ExamRoom object will be instantiated and called as such:
* ExamRoom obj = new ExamRoom(N);
* int param_1 = obj.seat();
* obj.leave(p);
*/