253. Meeting Rooms II
MediumDescription
給定一個會議時間區間的陣列
intervals,求同時進行的會議最多需要多少間會議室。
Example:
Input: intervals = [[0,30],[5,10],[15,20]] Output: 2
此題為 LeetCode Premium 題目。以下解法基於題目描述撰寫。
Intuition#
找「同時進行的最大會議數」,等價於掃描線找最大重疊深度。
- 把每個區間拆成「開始事件 +1」和「結束事件 -1」
- 按時間排序後掃描,累加值的最大值就是答案
- 或者用 min-heap 追蹤最早結束的會議
Approaches#
1: Min-Heap (Priority Queue)#
- 概念: 按起點排序後,用 min-heap 追蹤正在進行的會議的結束時間。如果最早結束的會議已經結束,就釋放那間會議室。
- 時間複雜度:
O(n log n) - 空間複雜度:
O(n)
class Solution {
fun minMeetingRooms(intervals: Array<IntArray>): Int {
intervals.sortBy { it[0] }
val heap = java.util.PriorityQueue<Int>()
for (interval in intervals) {
if (heap.isNotEmpty() && heap.peek() <= interval[0]) {
heap.poll()
}
heap.add(interval[1])
}
return heap.size
}
}⭐2: Sweep Line (Event Sorting)#
- 概念: 將所有起點和終點拆成事件,排序後掃描,追蹤同時進行的會議數
- 時間複雜度:
O(n log n) - 空間複雜度:
O(n)
class Solution {
fun minMeetingRooms(intervals: Array<IntArray>): Int {
val starts = intervals.map { it[0] }.sorted().toIntArray()
val ends = intervals.map { it[1] }.sorted().toIntArray()
var rooms = 0
var maxRooms = 0
var s = 0; var e = 0
while (s < starts.size) {
if (starts[s] < ends[e]) {
rooms++
maxRooms = maxOf(maxRooms, rooms)
s++
} else {
rooms--
e++
}
}
return maxRooms
}
}🔑 Takeaways#
- Pattern: 掃描線 (Sweep Line) — 將區間拆成事件點,排序後掃描求最大同時值
- 關鍵技巧: 分開排序 start 和 end 是一個巧妙的簡化:不需要配對,只需要知道「某個會議開始了」和「某個會議結束了」