题目重点:用结束先于开始的事件扫描,证明并发下界可通过复用房间达到。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 半开正时长区间,房间同质、无容量与设备限制;返回最少房间数。
- 同时刻结束可立即给新会议复用,空输入返回0。
解题路线
- 每会议拆成start:+1、end:-1事件,按(time,delta)排序。这样同刻-1先处理,不把刚结束与新开始同时计入。
- 扫描active,峰值是必须房间数下界,因为同时进行的会议不能同房。
- 可行上界用结束时间最小堆分配:已结束房间可复用,只有全部房间都忙才开新房;开新房时并发恰为房间总数,因此从不超过峰值。代码事件法计算数量,堆法可重建分配。
- 区间终点政策一改,tie策略随之改;闭区间相等也冲突需start先于end。不能只说“都是排序”而略过边界。
手动走一遍
训练[[0,30],[5,10],[15,20]]峰值2;[[0,5],[5,10]]只需1,而同刻事件顺序错误会得到2。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def minimum_rooms(meetings):
"""Half-open [start,end), positive duration; end events precede start ties."""
if any(start >= end for start,end in meetings):
raise ValueError("positive-duration meetings required")
events=[]
for start,end in meetings:
events.extend(((start,1),(end,-1)))
active=answer=0
for time,delta in sorted(events):
active+=delta
answer=max(answer,active)
return answer
复杂度
O(n log n)时间、O(n)事件空间;房间分配堆版O(n log r)处理加排序,r为结果。
易错点与追问
容易失分的边界
- 同刻先start导致多算房间。
- 用相邻不重叠布尔判断替代并发数。
- 把全局最大end与每个start比导致过算。
继续深挖
- 要输出每会议房号?
- 各房容量不同为何峰值下界不再充分?
- 一天大量整数时间戳能否用差分桶?
