题目重点:Tokyo 电面给会议室题名;用开始时间排序和结束时间堆求最大并发,并明确边界是训练假设。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版会议 [start,end),结束时刻可立刻复用房间;start=end 零时长占用 0。
- 输入时间可比较且同一时区,非法 end<start 报错;若闭区间,两会相接也算冲突。
解题路线
- 按 start 排序,维护仍在进行的会议 end 最小堆;处理新会议前弹出所有 end≤start 的房间。
- 把当前 end 压堆,堆大小就是此刻占用房间数,持续取最大值作为最少房间数。
- 也可把起点/终点拆事件 sweep line,端点相同时先处理结束;该 tie-break 正是半开区间语义。
- 若只求数量而不需房间 ID,可用双排序数组;若要返回具体排房,堆元素加 roomId。
手动走一遍
训练区间 [0,10)、[10,20)、[5,15):5 时占用 2 间;10 时第一间释放,第三个仍占一间,第二个复用释放房,最大并发 2。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
import heapq
def minimum_rooms(intervals):
"""Half-open [start,end) meetings; zero-duration meetings use no room."""
active_ends = []
peak = 0
for start, end in sorted(intervals):
if end < start:
raise ValueError("end before start")
if end == start:
continue
while active_ends and active_ends[0] <= start:
heapq.heappop(active_ends)
heapq.heappush(active_ends, end)
peak = max(peak, len(active_ends))
return peak
复杂度
n 个会议排序 O(n log n),每次堆操作 O(log n),额外空间 O(n)。
易错点与追问
容易失分的边界
- 结束等于开始仍占两间,与半开约定矛盾。
- 只看当前堆大小而忘记录历史峰值。
- 零时长会议处理未约定。
- 输入跨时区却按本地时钟直接比较。
继续深挖
- 如何分配房间 ID?
- 会议动态增删时怎样回答峰值?
- 若清场缓冲 10 分钟如何变更区间?
