题目地址:
https://www.lintcode.com/problem/1513/description
给定
n
n
n个座位,编号分别是
0
∼
n
−
1
0\sim n-1
0∼n−1,要求实现一个类,可以做两个操作:
1、就位,要求找到一个空位,其距离离其最近的非空位尽可能远,如果答案不唯一则找到下标最小的那一个空位;
2、离席,将某个非空位变成空位。
可以用TreeSet,离席很容易实现,操作就位时,如果所有座位都为空则就位在 0 0 0号位,否则尝试就位 0 0 0或 n − 1 n-1 n−1,然后遍历所有非空位,尝试相邻两个非空位的中点(如果中点不唯一则取靠左的),尝试完所有可能情况后取距离离其最近的非空位尽可能远的那个空位即可。代码如下:
import java.util.TreeSet;
public class ExamRoom {
private int n;
private TreeSet<Integer> treeSet;
public ExamRoom(int N) {
n = N;
treeSet = new TreeSet<>();
}
public int seat() {
if (treeSet.isEmpty()) {
treeSet.add(0);
return 0;
}
int res = 0, prev = 0, diff = treeSet.first();
for (int x : treeSet) {
int pos = prev + x >> 1;
if (pos - prev > diff) {
diff = pos - prev;
res = pos;
}
prev = x;
}
// 尝试n - 1号空位
if (n - 1 - prev > diff) {
res = n - 1;
}
treeSet.add(res);
return res;
}
public void leave(int p) {
treeSet.remove(p);
}
}
时间复杂度 O ( log n ) O(\log n) O(logn),空间 O ( n ) O(n) O(n)。