My solution using Heap and TreeMap
Used concept (-1, N) and different distance measuring from below link.\nhttps://leetcode.com/problems/exam-room/discuss/404676/Java-Two-TreeSets-Solution.-Both-
Used concept (-1, N) and different distance measuring from below link.\nhttps://leetcode.com/problems/exam-room/discuss/404676/Java-Two-TreeSets-Solution.-Both-Seat-and-Leave-O(log-n)-Time-Complexity\n\n\n```\n// 0 to x1\n// xn to xn+1\n// xn to last\n\nclass ExamRoom {\n\n     int N;\n     class Interval {\n        int x, y, dis;\n        String id; // for O(1) lookup\n\n        public Interval(int x, int y) {\n            this.x = x;\n            this.y = y;\n            if (x == -1) {\n                this.dis = y;\n            } else if (y == N) {\n                this.dis = N - 1 - x;\n            } else {\n                this.dis = Math.abs(x - y) / 2; // works for both odd and even distance. The dis is to the closest person, no matter on the left or right.\n            }\n            this.id = x + "_" + y;\n        }\n\n        // this is for TreeSet remove (Object o) method.\n        public boolean equals(Interval i) {\n            return this.id.equals(i.id);\n        }\n         \n        public String toString() {\n            return x + "_" + y + "_" + dis;            \n        }\n    }\n    \n    TreeMap<Integer, Interval> takenSeats;\n    PriorityQueue<Interval> maxHeap;\n    \n    public ExamRoom(int N) {\n        takenSeats = new TreeMap<>();\n        maxHeap = new PriorityQueue<>((a, b) -> {            \n            if(a.dis == b.dis) return a.x - b.x;\n            \n            return b.dis - a.dis;\n        });\n        this.N = N;\n        \n        Interval initial = new Interval(-1, N);\n        maxHeap.offer(new Interval(-1, N));\n        takenSeats.put(-1, initial);\n    }\n    \n    public int seat() {\n        int pos = 0;\n        Interval cand = maxHeap.poll(); \n        takenSeats.remove(cand.x);\n        \n        if (cand.x == -1) { // we keep -1\n            pos = 0;\n        } else if(cand.y == N) {\n            pos = N-1;\n        } else {\n            pos = (cand.y + cand.x) / 2;\n        }\n        \n        Interval oldInterval = new Interval(cand.x, pos);\n        Interval newInterval = new Interval(pos, cand.y);\n        \n        maxHeap.offer(oldInterval);\n        maxHeap.offer(newInterval);\n        takenSeats.put(cand.x, oldInterval);\n        takenSeats.put(pos, newInterval);\n        \n        return pos;   \n    }\n    \n    public void leave(int p) {\n        int startIndex = takenSeats.lowerKey(p);\n        mergeInterval(takenSeats.get(startIndex), takenSeats.get(p), maxHeap);\n    }\n    \n    private void mergeInterval(Interval i1, Interval i2, PriorityQueue<Interval> maxHeap) {\n        maxHeap.remove(i1);\n        maxHeap.remove(i2);\n        \n        takenSeats.remove(i1.x);\n        takenSeats.remove(i2.x);\n        \n        Interval newInterval = new Interval(i1.x, i2.y);\n        maxHeap.add(newInterval);\n        takenSeats.put(newInterval.x, newInterval);\n    }\n}\n\n/**\n * Your ExamRoom object will be instantiated and called as such:\n * ExamRoom obj = new ExamRoom(n);\n * int param_1 = obj.seat();\n * obj.leave(p);\n */\n```
[]