LeetCode 855. Exam Room
题目分析
In an exam room, there are
N
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 class
ExamRoom(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:
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 <= 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
.
思考
对有具体要求的数据结构实现,很难得的题目,题目要求明确,新建一个容量为N
的考试房间,每次向里放人或者向外赶人,放人要求必须放在离其他人最远的位置,这个数据结构的放置范围在
1∼109
1
∼
10
9
,直接使用数组模拟必然导致内存超出,所以我选用了内部元素有序的set
来坐内部数据结构,每次先检查0和最后一个位置是否坐了人,毕竟这两个位置只需要考虑一边,而其它位置的的选取则必然是在两个座位中间选取,max_len
变量记录最长的距离,idx
记录上一个同学的位置,遍历set
即可,删除时直接使用erase
。
代码实现
class ExamRoom {
public:
set<int> seats;
int n;
ExamRoom(int N) {
// 保存一下N
n = N;
}
int seat() {
// 寻找座位
int result = 0;
if (seats.size() != 0) {
result = 0;
int idx = 0;
int max_len = 0;
// 查看0是否占用
if (!seats.count(0)) {
// 注意,最后的那个位置和0处的距离是不需要除2的
max_len = *seats.begin() - 0;
result = 0;
}
auto it = seats.begin(), end = seats.end();
while (it != end) {
int len = (*it - idx) / 2;
if (len > max_len) {
max_len = len;
result = (*it + idx) / 2;
}
idx = *it;
++it;
}
// 看最后的位置有没有被占
if (!seats.count(n - 1)) {
int len = n - 1 - *seats.rbegin();
if (len > max_len) {
max_len = len;
result = n - 1;
}
}
}
seats.insert(result);
return result;
}
void leave(int p) {
seats.erase(seats.find(p));
}
};
感想
这道题可以说是做的非常难受了,我在1h28m的时候才把它AC掉,虽然在Leetcode上碰到好几个这样的题,绝对算不上陌生,可是真的在比赛里碰见时才能发现自己的水平的真的不够,多加练习,学习新的算法和数据结构才能让自己的能力更上一层楼。