#855
Medium
auto_awesome

LeetCode 题解工作台

考场就座

在考场里,有 n 个座位排成一行,编号为 0 到 n - 1 。 当学生进入考场后,他必须坐在离最近的人最远的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 号座位上。) 设计一个模拟所述考场的类。 实现 ExamRoom 类: ExamRoom…

category

3

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

中等 ·

bolt

答案摘要

考虑到每次 时都需要找到最大距离的座位,我们可以使用有序集合来保存座位区间。有序集合的每个元素为一个二元组 $(l, r)$,表示 和 之间(不包括 和 )的座位可以坐学生。初始时有序集合中只有一个元素 $(-1, n)$,表示 $(-1, n)$ 之间的座位可以坐学生。 另外,我们使用两个哈希表 和 来维护每个有学生的座位的左右邻居学生,方便我们在 时合并两个座位区间。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 堆 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

在考场里,有 n 个座位排成一行,编号为 0n - 1

当学生进入考场后,他必须坐在离最近的人最远的座位上。如果有多个这样的座位,他会坐在编号最小的座位上。(另外,如果考场里没有人,那么学生就坐在 0 号座位上。)

设计一个模拟所述考场的类。

实现 ExamRoom 类:

  • ExamRoom(int n) 用座位的数量 n 初始化考场对象。
  • int seat() 返回下一个学生将会入座的座位编号。
  • void leave(int p) 指定坐在座位 p 的学生将离开教室。保证座位 p 上会有一位学生。

 

示例 1:

输入:
["ExamRoom", "seat", "seat", "seat", "seat", "leave", "seat"]
[[10], [], [], [], [], [4], []]
输出:
[null, 0, 9, 4, 2, null, 5]
解释:
ExamRoom examRoom = new ExamRoom(10);
examRoom.seat(); // 返回 0,房间里没有人,学生坐在 0 号座位。
examRoom.seat(); // 返回 9,学生最后坐在 9 号座位。
examRoom.seat(); // 返回 4,学生最后坐在 4 号座位。
examRoom.seat(); // 返回 2,学生最后坐在 2 号座位。
examRoom.leave(4);
examRoom.seat(); // 返回 5,学生最后坐在 5 号座位。

 

提示:

  1. 1 <= n <= 109
  2. 保证有学生正坐在座位 p 上。
  3. seat 和 leave 最多被调用 104 次。
lightbulb

解题思路

方法一:有序集合 + 哈希表

考虑到每次 seat()\text{seat}() 时都需要找到最大距离的座位,我们可以使用有序集合来保存座位区间。有序集合的每个元素为一个二元组 (l,r)(l, r),表示 llrr 之间(不包括 llrr)的座位可以坐学生。初始时有序集合中只有一个元素 (1,n)(-1, n),表示 (1,n)(-1, n) 之间的座位可以坐学生。

另外,我们使用两个哈希表 left\textit{left}right\textit{right} 来维护每个有学生的座位的左右邻居学生,方便我们在 leave(p)\text{leave}(p) 时合并两个座位区间。

时间复杂度 O(logn)O(\log n),空间复杂度 O(n)O(n)。其中 nn 为考场的座位数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class ExamRoom:
    def __init__(self, n: int):
        def dist(x):
            l, r = x
            return r - l - 1 if l == -1 or r == n else (r - l) >> 1

        self.n = n
        self.ts = SortedList(key=lambda x: (-dist(x), x[0]))
        self.left = {}
        self.right = {}
        self.add((-1, n))

    def seat(self) -> int:
        s = self.ts[0]
        p = (s[0] + s[1]) >> 1
        if s[0] == -1:
            p = 0
        elif s[1] == self.n:
            p = self.n - 1
        self.delete(s)
        self.add((s[0], p))
        self.add((p, s[1]))
        return p

    def leave(self, p: int) -> None:
        l, r = self.left[p], self.right[p]
        self.delete((l, p))
        self.delete((p, r))
        self.add((l, r))

    def add(self, s):
        self.ts.add(s)
        self.left[s[1]] = s[0]
        self.right[s[0]] = s[1]

    def delete(self, s):
        self.ts.remove(s)
        self.left.pop(s[1])
        self.right.pop(s[0])


# Your ExamRoom object will be instantiated and called as such:
# obj = ExamRoom(n)
# param_1 = obj.seat()
# obj.leave(p)
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Check if your implementation updates intervals correctly after each seat and leave operation.

  • question_mark

    Consider how your heap or ordered set handles boundary seats and tie-breaking rules.

  • question_mark

    Ensure time complexity is efficient for up to 10^4 operations with large n.

warning

常见陷阱

外企场景
  • error

    Failing to correctly merge intervals after a leave() call, leading to incorrect distance calculations.

  • error

    Choosing the wrong seat when multiple positions yield the same maximum distance.

  • error

    Scanning the entire seat row instead of using a heap or ordered set, causing timeouts for large n.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Implement Exam Room in a circular seating arrangement where the first and last seats are adjacent.

  • arrow_right_alt

    Allow multiple students to enter simultaneously and assign them to maximize distance collectively.

  • arrow_right_alt

    Track the k farthest empty seats instead of just the maximum distance seat for alternative seat selection strategies.

help

常见问题

外企场景

考场就座题解:堆 | LeetCode #855 中等