Python heapq solution with comments, seat O(logn) leave O(n)
\nimport heapq\nclass ExamRoom(object):\n\n    def dist(self, x, y):\n        # This handles the case when there are 0 or 1 students.\n        if x == -1 or y =
```\nimport heapq\nclass ExamRoom(object):\n\n    def dist(self, x, y):\n        # This handles the case when there are 0 or 1 students.\n        if x == -1 or y == self.N:\n            return abs(y - 1 - x)\n        else:\n            # This will be the min diff when we decide to seat at (y + x) / 2.\n            return abs(y-x) /2 \n\n    def __init__(self, N):\n        """\n        :type N: int\n        """\n        self.N = N\n\n        # Min heap - (-dist, x, y)\n        # If dist is same, ordering will be based on x (which will handle the\n        # clause for smallest possible seat).\n        self.h = []\n        heapq.heappush(self.h, (-self.dist(-1, N), -1, N))\n        \n    def seat(self):\n        """\n        :rtype: int\n        """\n\n        # Pop the max distance segment from the heap.\n        d, x, y = heapq.heappop(self.h)\n\n        ans = None\n        if x == -1:\n            # If x == -1, the furthest seat will be at 0 and not at midpoint.\n            ans = 0\n        elif y == self.N:\n            # If x == N , the furthest seat will be at N-1 and not at midpoint.\n            ans = self.N - 1\n        else:\n            # Furthest seath will be (x + y) / 2\n            ans = (x + y) / 2\n\n        # Push intervals formed after seating back into the heap.\n        heapq.heappush(self.h, (-self.dist(x, ans), x, ans))\n        heapq.heappush(self.h, (-self.dist(ans, y), ans, y))\n        return ans\n\n    def leave(self, p):\n        """\n        :type p: int\n        :rtype: None\n        """\n\n        # Let\'s say we want to remove 4 when the state of the hall is\n        # [0, 2, 4, 6, 9]. There will be two items in the heap - [-1, 2, 4] and\n        # [-1, 4, 6]. We need to remove both of these and merge them into a\n        # single interval [-2, 2, 6]. Here first=[-1, 2, 4], second=[-1, 4, 6]\n        # We need to heapify once we remove this and insert the merged interval.\n        first, second = None, None\n        for interval in self.h:\n            if interval[2] == p:\n                first = interval\n            if interval[1] == p:\n                second = interval\n            if first and second:\n                break\n        self.h.remove(first)\n        self.h.remove(second)\n        heapq.heapify(self.h)\n        heapq.heappush(self.h, (-self.dist(first[1], second[2]), first[1], second[2]))\n```
[]