Java simple O(logN) for both seat() and leave()
Extended the idea of zzzliu\'s solution to make it log(n) for both seat() and leave(). The idea is to basically maintain the gaps or intervals in a treeset and 
Extended the idea of [zzzliu\'s](https://leetcode.com/problems/exam-room/discuss/193295/My-Elegant-Java-Solution-Beats-99.84) solution to make it log(n) for both seat() and leave(). The idea is to basically maintain the gaps or intervals in a treeset and track their boundaries in a hashmap. Code is self-explanatory. \n\n```\nclass ExamRoom {\n\n    int n;\n    TreeSet<Interval> availableGaps;\n    Map<Integer, Interval> boundaries; // track boundaries of intervals\n    \n    public ExamRoom (int N) {\n        this.n = N;\n        availableGaps = new TreeSet<>((i, j) -> {\n            if (i.length != j.length) return j.length - i.length;\n            return i.start - j.start;\n        });\n        boundaries = new HashMap<>();\n        addInterval(0, N-1);\n    }\n    \n    public int seat() {\n        Interval top = availableGaps.pollFirst();\n        boundaries.remove(top.start);\n        boundaries.remove(top.end);\n        // Calculate result\n        int result = 0;\n        if (top.start == 0) {\n            result = 0;\n        } else if (top.end == n-1) {\n            result = n-1;\n        } else {\n            result = top.start + top.length;\n        }\n        // Add intervals\n        if (result > top.start) {\n            addInterval(top.start, result-1);\n        }\n        if (result < top.end) {\n            addInterval(result+1, top.end);\n        }\n        return result;\n    }\n    \n    public void leave(int p) {\n        Interval prev = boundaries.get(p-1);\n        Interval next = boundaries.get(p+1);\n        if (prev != null) {\n            removeInterval(prev);\n        }\n        if (next != null) {\n            removeInterval(next);\n        }\n        // Add new interval\n        addInterval(prev == null ? p : prev.start, next == null ? p : next.end);\n    }\n    \n    private void addInterval (int start, int end) {\n        Interval temp = new Interval(start, end);\n        availableGaps.add(temp);\n        boundaries.put(start, temp);\n        boundaries.put(end, temp);\n    }\n    \n    private void removeInterval (Interval temp) {\n        availableGaps.remove(temp);\n        boundaries.remove(temp.start);\n        boundaries.remove(temp.end);\n    }\n    \n    class Interval {\n        int start;\n        int end;\n        int length;\n        public Interval(int start, int end) {\n            this.start = start;\n            this.end = end;\n            if (start == 0 || end == n - 1) {\n                this.length = end - start;\n            } else {\n                this.length = (end - start) / 2;\n            }\n        }\n    }\n}\n```
[]