855. Exam Room

这道题的难点有两个
首先最难的我感觉是对边界条件的处理
再次是数据结构的选择。
边界条件对于两个edge的处理很是头疼, 因为题目中说要找maximizes the distance to the closest person的位置,最容易想的就是找一个距离最大的interval。然后做这个interval中间。这样问题就来了,如果这个interval的一边是边界怎么处理。如果一边是边界而且为空的话难道还坐中间吗?
这就是一个坑!
但反过来想一下,为什么我们要找最大的interval? 我们直接找距离两边最大的位置不就好了吗,在处理每个interval的时候我们直接求距离最大的位置。
如果没有人,则直接放到0。
如果有人,则从第一个人开始看起。为了去重我们只看每个人左边的空位,每个人和他上一个相减得到中间的位置,然后看这个中间的位置离邻居的距离是不是最大。如果没有左邻,则只需要看一下0到这个人的距离。 遍历完之后我们可以看一下最后一个人是不是在N -1的位置上,如果不在的话再看一下最后这个位置。
看代码

class ExamRoom {
    int N;
    TreeSet set;
    public ExamRoom(int N) {
        this.N = N;
        set = new TreeSet<>();
    }
    public int seat() {
        Iterator it = set.iterator();
        int largestInterval = 0;
        int prev = -1;
        int bestPos = 0;
        while (it.hasNext()) {
            int cur = it.next();
            if (prev == -1) {
                largestInterval = cur;
            } else {
                int mid = prev + (cur - prev) / 2;
                if (mid - prev > largestInterval) {
                    bestPos = mid;
                    largestInterval = mid - prev;
                }
            }
            prev = cur; 
        }
        
        if (prev != N - 1 && prev != -1) {
            if (N - 1 - prev > largestInterval) {
                largestInterval = N - 1 - prev;
                bestPos = N - 1;
            }
        }
        if (largestInterval == 0 && prev != -1) return -1;
        set.add(bestPos);
        return bestPos;
    }
    
    public void leave(int p) {
        set.remove(p);
    }
}

这种代码的时间复杂度是放的时候是O(N), 离开的时候是 O(logN)

另外一种做法是建一个priority Queue,
按每个interval能给的最大dist排序 ,不是按interval的length排序!!
这里的trick是让Interval这个类帮你去算distance不是自己每次算,否则累死了。
这样比较容易写。
看一下代码, 是从高票答案学习来的。

class ExamRoom {
    Queue queue;
    int N;
    public ExamRoom(int N) {
        this.N = N;
        queue = new PriorityQueue(new Comparator(){
            public int compare(Interval o1, Interval o2) {
                if (o1.dist != o2.dist) return o1.dist > o2.dist ? -1 : 1;
                return o1.left - o2.left;
            }
        });
        queue.offer(new Interval(-1, N, N));
    }
    
    public int seat() {
        Interval itv = queue.poll();
        int seat = 0;
        if (itv.left == -1) {
            seat = 0;
        } else if (itv.right == N) {
            seat = N - 1;
        } else {
            seat = itv.left + (itv.right - itv.left) / 2;
        }
        queue.offer(new Interval(itv.left, seat, N));
        queue.offer(new Interval(seat, itv.right, N));
        return seat;
    }
    
    public void leave(int p) {
        Interval a = null;
        Interval b = null;
        for (Interval itv : queue) {
            if (itv.left == p) {
                b = itv;
            } else if (itv.right == p) {
                a = itv;
            }
        }
        queue.remove(a);
        queue.remove(b);
        Interval c = new Interval(a.left, b.right, N);
        
        queue.offer(c);        
    }
}
class Interval {
    int left, right, dist;
    public Interval(int left, int right, int N) {
        this.left = left;
        this.right = right;
        if (left == -1) {
            this.dist = right;
        } else if (right == N) {
            this.dist = N - 1 - left;
        } else {
            this.dist = (right - left) / 2;
        }
    }
}

你可能感兴趣的:(855. Exam Room)