Meeting Rooms II
Table of Contents + β
Meeting Rooms II is the question that separates people who memorize from people who think. Meeting Rooms only asked yes or no. This one asks how many rooms you need so no meeting clashes. The answer is the largest number of meetings happening at the same time. Finding that peak is the real puzzle.
π― The Problem
You get a list of meetings and find the fewest rooms needed.
- Each meeting is a pair: a start time and an end time.
- Find the smallest number of rooms so no two meetings clash.
- Two meetings clash when both are running at the same instant.
- The answer is the peak overlap: the most meetings live at one moment.
- A meeting ending at
10and another starting at10can share one room.
Input: intervals = [[0, 30], [5, 10], [15, 20]]Output: 2
Explanation: At time 5, the meetings [0, 30] and [5, 10] are both live.That is two at once, so two rooms are enough for the whole day.Here is the input drawn on a number line. Around time 5 to 10, two meetings run together, and that is the peak.
π’ Approach 1: Count At Every Time Point (Brute Force)
Walk the clock and count live meetings at each tick.
The idea:
- Step over every time point on the clock.
- At each point, count how many meetings are live.
- The largest count you see is the answer.
Why it is weak:
- The clock can be huge. Times may go up to a million.
- For each tick you scan all meetings.
- The cost depends on how big the numbers are, not just the meeting count.
Here is the sweep-every-time-point code:
def min_meeting_rooms(intervals): if not intervals: return 0
first = min(start for start, end in intervals) last = max(end for start, end in intervals) best = 0
for time in range(first, last + 1): active = sum(start <= time < end for start, end in intervals) best = max(best, active) return bestβ‘ Approach 2: Min-Heap Of End Times (Better)
The idea in one line: keep the rooms in use as a min-heap of their end times.
The idea:
- Sort the meetings by start time.
- A min-heap always hands you the smallest value fast.
- Here the smallest value is the room that frees up soonest.
How it works:
- For each meeting, look at the heap top, the earliest end.
- If that end is at or before this start, that room is free, so pop it.
- Push this meetingβs end, because it takes a room.
- The heap size right now is the rooms in use. Track its peak.
Why it is fast:
- Sorting is O(n log n). Each heap push and pop is O(log n).
- Done n times, the total stays O(n log n).
Here is the min-heap code for that idea:
import heapq
def min_meeting_rooms(intervals): intervals.sort() rooms = []
for start, end in intervals: if rooms and rooms[0] <= start: heapq.heappop(rooms) heapq.heappush(rooms, end)
return len(rooms)β‘ Approach 3: Split Starts And Ends (Best)
The idea in one line: sort starts and ends apart, then sweep both with two pointers and no heap.
The idea:
- Take all start times into one list and all end times into another.
- Sort both lists.
- Sweep through time with two pointers.
How it works:
- Walk the starts in order. Compare each start with the smallest end not yet passed.
- If the start is before that end, a new meeting begins while an old one runs, so add a room and track the peak.
- If the start is at or after that end, an old meeting freed a room first, so reuse it and move the end pointer forward.
Why it is fast:
- Two sorts cost O(n log n). The sweep is O(n).
- No heap structure to maintain.
Here is the heap version as a flow.
Steps to Solve
- Sort the meetings by start time.
- Make an empty min-heap that will hold end times.
- For each meeting, if the smallest end in the heap is at or before this start, pop it, because that room is free.
- Push this meetingβs end onto the heap.
- The current heap size is the rooms in use. Track the largest size you see.
- Return that largest size.
This Python version uses heapq, the built-in min-heap, to track end times.
import heapq
def min_meeting_rooms(intervals): intervals.sort(key=lambda block: block[0]) # sort by start heap = [] # min-heap of end times rooms = 0
for start, end in intervals: if heap and heap[0] <= start: # earliest room is free heapq.heappop(heap) heapq.heappush(heap, end) # this meeting takes a room rooms = max(rooms, len(heap)) # track the peak return rooms
intervals = [[0, 30], [5, 10], [15, 20]]print(min_meeting_rooms(intervals))The output of the above code will be:
2Now let us walk through the Python heap version line by line and see why each part is written this way.
def min_meeting_rooms(intervals): intervals.sort(key=lambda block: block[0]) heap = [] rooms = 0We sort by start so we meet the meetings in time order. The heap will hold the end times of meetings that are currently using a room. rooms will remember the most rooms we ever needed at once.
for start, end in intervals: if heap and heap[0] <= start: heapq.heappop(heap)For each meeting we look at heap[0], which in a min-heap is always the smallest end time, the room that frees up soonest. The check heap[0] <= start reads as βthat room is already free by the time this meeting starts.β So we pop it, because we can reuse that room. We use <= because a meeting ending exactly at this start has already finished.
heapq.heappush(heap, end) rooms = max(rooms, len(heap)) return roomsEvery meeting needs a room, so we always push its end onto the heap. We did the pop first so a freed room gets reused instead of adding a new one. The heap size right now is the number of rooms in use, so we update rooms with the peak. At the end rooms holds the most rooms ever needed, which is the answer.
β±οΈ Time and Space Complexity
The brute force over every time point depends on how large the times are, so it can be very slow. The heap version sorts in O(n log n) and does n heap operations each O(log n), so the total is O(n log n). The split-events version sorts two lists in O(n log n) then sweeps in O(n), so it is also O(n log n). Both use O(n) extra space for the heap or the event lists. The deep idea is that the answer is the peak overlap, the most meetings live at once.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Brute force over every time point | O(n Γ maxTime) | O(1) |
| Min-heap of end times | O(n log n) | O(n) |
| Split starts and ends, two pointers | O(n log n) | O(n) |
Tip
The answer is never about the total meetings. It is the largest number happening at the same instant. Both the heap and the split-events sweep are just clean ways to find that peak.
π§© Key Takeaways
- β The answer is the peak overlap, the most meetings live at the same time.
- β Sort by start so you meet the meetings in time order.
- β A min-heap of end times tells you the room that frees up soonest.
- β Reuse a room when its end is at or before the next start.
- β The heap size at its largest is the number of rooms you need.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does Meeting Rooms II ask you to return?
Why: It asks for the fewest rooms needed, which equals the most meetings happening at the same instant.
- 2
In the heap solution, what does the top of the min-heap represent?
Why: A min-heap keeps the smallest end on top, which is the room that becomes free the soonest.
- 3
When can we reuse a room for the next meeting?
Why: If the soonest-ending room finishes by the time the next meeting starts, that room is free to reuse.
- 4
What is the time complexity of the min-heap solution?
Why: Sorting is O(n log n) and each of the n heap operations is O(log n), so the total is O(n log n).