Meeting Rooms Problem Minimum Rooms Required in DSA Rust - Time & Space Complexity
We want to find out how the time needed to find the minimum number of meeting rooms changes as the number of meetings grows.
How does the algorithm handle more meetings and what costs increase?
Analyze the time complexity of the following code snippet.
fn min_meeting_rooms(intervals: &mut Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.0);
let mut heap = std::collections::BinaryHeap::new();
let mut max_rooms: i32 = 0;
for interval in intervals.iter() {
while let Some(std::cmp::Reverse(top)) = heap.peek() {
if *top > interval.0 {
break;
}
let _ = heap.pop();
}
heap.push(std::cmp::Reverse(interval.1));
if (heap.len() as i32) > max_rooms {
max_rooms = heap.len() as i32;
}
}
max_rooms
}
This code sorts meetings by start time, then uses a heap to track ongoing meetings and find the minimum rooms needed.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through all meetings once.
- How many times: Once for each meeting (n times).
- Secondary operation: Heap operations (push and pop) inside the loop.
- How many times: Up to n times, each heap operation costs log n.
As the number of meetings increases, sorting takes more time, and each meeting causes heap operations that grow with the number of meetings.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Sorting ~ 10 log 10 = 33, Heap ops ~ 10 log 10 = 33 |
| 100 | Sorting ~ 100 log 100 = 664, Heap ops ~ 100 log 100 = 664 |
| 1000 | Sorting ~ 1000 log 1000 = 9966, Heap ops ~ 1000 log 1000 = 9966 |
Pattern observation: The total operations grow roughly like n times log n, which grows faster than just n but slower than n squared.
Time Complexity: O(n log n)
This means the time needed grows a bit faster than the number of meetings, mainly because of sorting and heap operations.
[X] Wrong: "Since we only loop once through meetings, the time is O(n)."
[OK] Correct: Sorting and heap operations inside the loop add extra work that depends on log n, making the total time more than just O(n).
Understanding this time complexity helps you explain how your solution scales and why sorting and data structures like heaps matter in scheduling problems.
What if we used a simple list instead of a heap to track meeting end times? How would the time complexity change?
Practice
Solution
Step 1: Understand the problem goal
The problem asks for the minimum number of rooms needed so that no two meetings overlap in the same room.Step 2: Clarify what is being counted
We count how many meetings overlap at the same time to know how many rooms are needed.Final Answer:
The minimum number of rooms needed so that no meetings overlap in the same room -> Option CQuick Check:
Minimum rooms = max overlapping meetings [OK]
- Confusing total meetings with rooms needed
- Thinking about meeting durations instead of overlaps
- Assuming rooms equal to total meetings
Solution
Step 1: Identify the need to track earliest ending meeting
We need to know which meeting ends earliest to free a room for the next meeting.Step 2: Choose data structure for efficient retrieval
A binary heap (priority queue) efficiently gives the earliest ending meeting in O(log n) time.Final Answer:
Binary heap (priority queue) to track earliest ending meeting -> Option DQuick Check:
Priority queue tracks earliest end time [OK]
- Using HashMap which doesn't keep order
- Using LinkedList which is inefficient for min retrieval
- Using Vec without sorting or heap structure
let intervals = vec![(0, 30), (5, 10), (15, 20)];
// Function returns minimum rooms required
let result = min_meeting_rooms(intervals);
println!("{}", result);
fn min_meeting_rooms(mut intervals: Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.0);
let mut heap = std::collections::BinaryHeap::new();
for interval in intervals {
if let Some(&Reverse(end)) = heap.peek() {
if interval.0 >= end {
heap.pop();
}
}
heap.push(Reverse(interval.1));
}
heap.len() as i32
}Solution
Step 1: Sort intervals by start time
Sorted intervals: (0,30), (5,10), (15,20)Step 2: Use min-heap to track end times and count rooms
First meeting (0,30): push 30
Second meeting (5,10): 5 < 30, push 10 (rooms=2)
Third meeting (15,20): 15 >= 10, pop 10, push 20 (rooms=2)Final Answer:
2 -> Option BQuick Check:
Max overlapping meetings = 2 [OK]
- Not sorting intervals before processing
- Not popping from heap when room frees
- Counting total meetings instead of overlaps
fn min_meeting_rooms(mut intervals: Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.1);
let mut heap = std::collections::BinaryHeap::new();
for interval in intervals {
if let Some(&Reverse(end)) = heap.peek() {
if interval.0 >= end {
heap.pop();
}
}
heap.push(Reverse(interval.1));
}
heap.len() as i32
}Solution
Step 1: Check sorting criteria
The code sorts intervals by end time, but we must sort by start time to process meetings in order.Step 2: Understand impact on heap logic
Sorting by end time breaks the logic of comparing current start with earliest end, leading to wrong room count.Final Answer:
Sorting intervals by end time instead of start time causes incorrect room count -> Option AQuick Check:
Sort by start time, not end time [OK]
- Sorting by end time instead of start time
- Confusing heap usage with wrong keys
- Ignoring heap pop condition
Solution
Step 1: Sort intervals by start time
Sorted: (1,4), (2,5), (3,6), (7,9), (10,11)Step 2: Track overlapping meetings with min-heap
Push end 4 (room 1)
Next start 2 < 4, push 5 (room 2)
Next start 3 < 4, push 6 (room 3)
Next start 7 >= 4, pop 4, pop 5, pop 6, push 9 (room 1)
Next start 10 >= 9, pop 9, push 11 (room 1)
Max rooms used simultaneously = 3Final Answer:
3 -> Option AQuick Check:
Max overlaps at once = 3 rooms [OK]
- Not sorting intervals before processing
- Counting total meetings instead of overlaps
- Not popping freed rooms from heap
Ready to prove it?
Pass the test and this pattern moves unknown
