题目地址:
https://leetcode.com/problems/exam-room/
有
n
n
n个座位,下标是
0
∼
n
−
1
0\sim n - 1
0∼n−1。要求实现一个类,可以做如下操作:
1、就位。要求找到一个下标尽量小的空位,使得该位子与离其最近的有人的座位的距离尽量大,返回就位的座位下标;
2、离位。将某个位置上的人离开。
题目保证每个操作都合法。
可以用TreeSet来做。seat的时候,先枚举座位 0 0 0,然后枚举相邻的两个位子的中点(中点不唯一则取靠左的那个),最后枚举座位 n − 1 n-1 n−1,找到最近的距离最远的座位即可。leave的时候直接从TreeSet里删除。代码如下:
import java.util.TreeSet;
public class ExamRoom {
private TreeSet<Integer> seat;
private int n;
public ExamRoom(int N) {
n = N;
seat = new TreeSet<>();
}
public int seat() {
if (seat.isEmpty()) {
seat.add(0);
return 0;
}
// 枚举座位0
int left = -1, pos = 0, dist = seat.first();
for (int x : seat) {
if (left == -1) {
left = x;
continue;
}
if (dist < x - left >> 1) {
dist = x - left >> 1;
pos = left + dist;
}
left = x;
}
// 枚举座位n - 1
if (dist < n - 1 - seat.last()) {
pos = n - 1;
}
// 就坐
seat.add(pos);
return pos;
}
public void leave(int p) {
seat.remove(p);
}
}
seat时间复杂度 O ( n ) O(n) O(n),leave时间复杂度 O ( log n ) O(\log n) O(logn),空间 O ( n ) O(n) O(n)。