253. 会议室 II(中等)

Blind 75 › 253. 会议室 II(中等) (第 5 章)
文章工具

题目

给定若干场会议,每场用 [开始时间, 结束时间) 表示;问:要让所有会议都能按时开完,最少需要准备多少间会议室。

换句话说:在任意一个时刻,数一数同时有多少场会议正在进行;这个“同时进行”的最大值,就是答案。

自造示例:[[1,4],[2,5],[4,7],[6,9]] → 2(第 1、2 场重叠需要 2 间;[4,7] 在 4 点接上刚结束的 [1,4],[6,9] 在 6 点接上已结束的 [2,5])。

再看一个需要 3 间的示例:[[0,3],[1,4],[2,5],[3,6]] → 3(在 2.5 时,[0,3]、[1,4]、[2,5] 同时进行)。

约束:会议数 0 ~ 104;每场恰有两个整数,0 ≤ 开始时间 < 结束时间 ≤ 106。

思路

一句话:最少会议室数 = 同一时刻同时进行的会议数的最大值;所以问题变成求时间轴上的“最高水位”。

最直白的做法:把时间轴打成一格一格,从 0 秒到最大结束时间逐时刻统计正在进行多少场会议。若最大结束时间记为 M,这样做要 O(M) 次扫描;M 到 106 还能做,但 M 更大就崩,何况大量“没有任何会议变化”的时刻是重复劳动。

关键观察:并发人数只会在某场会议开始或某场会议结束的瞬间发生变化。因此只需把每个会议拆成两个事件:开始 +1、结束 -1,按时间排序后从左到右累加,过程中出现的最大值就是答案。这就是扫描线 / 差分思路。

另一个更直观的思考:先把会议按开始时间排序。处理一个新会议时,只关心当前最早空出来的房间够不够早:若最早结束时间 ≤ 当前开始时间,就直接复用那个房间;否则只能开新房间。要持续拿到“最早结束时间”,用小根堆最合适。

于是做法确定为:按开始时间排序 + 小根堆维护当前正在使用的所有房间的结束时间。

解法

把每一间会议室看成一个“被占用的时间槽”,房间里记录它什么时候结束;小根堆堆顶 top 就是这些房间里最早结束的那个时间。

  1. 把 intervals 按开始时间升序排序;空数组直接返回 0。
  2. 准备一个空的小根堆 pq,存放当前已占用会议室的结束时间。
  3. 遍历每个 [start, end]:
    • 若 start ≥ pq.top(),说明最早结束的房间已经空出,弹出它(用 ≥,因为 4 点结束、4 点开始不算重叠)。
    • 无论是否弹出,都把当前会议的 end 入堆:它此刻占用了一个房间(复用的旧房间或新开的房间)。
  4. 遍历结束后,堆的大小就是所需会议室数的峰值。
当前会议开始堆顶(最早结束)能否复用?操作操作后堆
[1,4]1空—入 4[4]
[2,5]242 ≥ 4 ? 否入 5[4,5]
[4,7]444 ≥ 4 ? 是出 4、入 7[5,7]
[6,9]656 ≥ 5 ? 是出 5、入 9[7,

🔒

本篇为付费内容

您已阅读试读部分,购买后即可解锁全文。

⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。

还没有评论,来说两句?

发表评论

欢迎交流技术细节;广告与人身攻击会被删除。

在线咨询