文章目录
- 题目
- 思路
- 代码
- 复杂度分析
- 时间复杂度
- 空间复杂度
- 结果
- 总结
题目
题目链接🔗
在考场里,有 n n n 个座位排成一行,编号为 0 0 0 到 n − 1 n - 1 n−1。
当学生进入考场后,他必须坐在离最近的人最远的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 0 0 号座位上。)
设计一个模拟所述考场的类。
实现 E x a m R o o m ExamRoom ExamRoom 类:
E x a m R o o m ( i n t n ) ExamRoom(int\,n) ExamRoom(intn) 用座位的数量 n 初始化考场对象。
i n t s e a t ( ) int\,seat() intseat() 返回下一个学生将会入座的座位编号。
v o i d l e a v e ( i n t p ) void\,leave(int\,p) voidleave(intp) 指定坐在座位 p p p 的学生将离开教室。保证座位 p p p 上会有一位学生。
示例 1:
输入:
[“ExamRoom”, “seat”, “seat”, “seat”, “seat”, “leave”, “seat”]
[[10], [], [], [], [], [4], []]
输出: [null, 0, 9, 4, 2, null, 5]
解释:
ExamRoom examRoom = new ExamRoom(10); examRoom.seat(); // 返回 0,房间里没有人,学生坐在 0 号座位。
examRoom.seat(); // 返回 9,学生最后坐在 9 号座位。
examRoom.seat(); // 返回 4,学生最后坐在 4 号座位。 examRoom.seat(); // 返回 2,学生最后坐在2 号座位。
examRoom.leave(4);
examRoom.seat(); // 返回 5,学生最后坐在 5 号座位。
提示:
- 1 ≤ n ≤ 1 0 9 1 \leq n \leq 10^9 1≤n≤109
- 保证有学生正坐在座位 p p p 上。
- s e a t seat seat 和 l e a v e leave leave 最多被调用 1 0 4 10^4 104 次。
思路
这个问题可以通过模拟的方式来解决。我们需要维护一个座位集合,每次调用 seat() 时,找到第一个满足条件的座位分配给学生,并在调用 leave(int p) 时,释放该座位。
代码
class ExamRoom {
public:set<int>st;int n;ExamRoom(int N) {n = N;}int seat() {if (st.empty()) {st.insert(0); return 0;}int pre = *st.begin(), idx = 0, mx = pre;for (auto u : st) {if ((u - pre) / 2 > mx) {idx = (u + pre) / 2;mx = (u - pre) / 2;}pre = u; }if (n - 1 - pre > mx) {idx = n - 1;}st.insert(idx);return idx;}void leave(int p) {st.erase(p);}
};
复杂度分析
时间复杂度
O ( N ) O(N) O(N),其中 N N N 是座位集合 s t st st 的大小。
空间复杂度
O ( N ) O(N) O(N),需要存储所有已占用的座位编号。
结果
总结
本题是一个模拟题,关键在于理解如何模拟座位的分配和释放过程。通过维护一个座位集合,我们可以有效地找到满足条件的座位,并在学生离开时释放座位。这种方法简单且高效,适用于需要管理有限资源的场景。