Given an array intervals, where every entry [start, end] represents one meeting, find the minimum number of conference rooms needed to hold every meeting without a scheduling conflict. An end time is exclusive, so a room becomes available for another meeting beginning at the same time.
Example 1
Input: intervals = [[0,30],[5,10],[15,20]]
Output: 2
Explanation: Meeting [0,30] overlaps with both shorter meetings. Meetings [5,10] and [15,20] can share a second room.
Example 2
Input: intervals = [[0,8],[8,10]]
Output: 1
Explanation: Meeting [0,8] releases the room exactly at time 8, allowing meeting [8,10] to use the same room.
Brute Force Approach
The required room count reaches a new peak only at a meeting start time. Counting all active meetings at every start time therefore reveals the largest overlap without checking every possible clock value.
For a chosen start time, an active interval has already started but has not yet ended. The largest active count across all meeting starts becomes the answer.
Algorithm
Begin with
maximumRooms = 0, so the largest overlap can be recorded as every meeting start is examined.Select each meeting start time because room demand can rise only at a new start.
Reset
currentRooms = 0for the selected time because every overlap count belongs to one independent time point.Scan every interval and count an interval only when
start <= time < end, preserving the exclusive end-time rule.Compare
currentRoomswithmaximumRoomsafter the full scan because the completed count represents all simultaneous meetings at the selected time.Repeat the scan for every meeting start because any maximum overlap must begin at a meeting start.
Return
maximumRoomsbecause the greatest simultaneous overlap equals the minimum number of rooms.
Dry Run
meeting-rooms-ii-brute-approach
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Finds the minimum room count by direct overlap checks. int minMeetingRooms(vector<vector<int>>& intervals) { int maximumRooms = 0; // Test every point capable of increasing overlap. for (int i = 0; i < intervals.size(); i++) { int time = intervals[i][0]; int currentRooms = 0; // Count meetings active at the selected start. for (int j = 0; j < intervals.size(); j++) { // An exclusive end releases the room on equality. if (intervals[j][0] <= time && time < intervals[j][1]) { currentRooms++; } } // Preserve the greatest simultaneous meeting count. maximumRooms = max(maximumRooms, currentRooms); } return maximumRooms; }};// Driver codeint main() { vector<vector<int>> intervals = {{0, 30}, {5, 10}, {15, 20}}; Solution obj; cout << obj.minMeetingRooms(intervals) << endl; return 0;}Complexity Analysis
Time Complexity: O(N2), where N is the number of intervals, because each of the N start times may require scanning all N intervals.
Space Complexity: O(1), because only a few counters and the selected start time use auxiliary space.
Better Approach
The direct method repeats overlap checks. Sorting meetings by start time removes repeated checks, while a min-heap stores the end times of meetings that are currently occupying rooms. The smallest heap value always represents the meeting that will finish first.
Before a new meeting begins, remove every end time less than or equal to its start time, because those meetings have already ended and their rooms are available again. Then add the current meeting’s end time to the heap. The maximum heap size seen during the process gives the largest number of meetings running at the same time.
Algorithm
Handle an empty interval list first because no meeting requires a room.
Sort all intervals by start time, allowing meetings to be processed in chronological order.
Keep a min-heap of end times of meetings currently occupying rooms, because the smallest end time identifies the meeting that finishes first.
Remove every heap value less than or equal to the current start time, because those meetings have already ended and their rooms are free.
Push the current meeting’s end time into the heap, because this meeting is now occupying a room.
Update
maximumRoomsusing the heap size, because the heap contains the end times of all meetings currently occupying rooms.Return
maximumRooms, because the maximum number of simultaneously active meetings equals the minimum number of rooms required.
Dry Run
meeting-rooms-ii-better-approach
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Finds the minimum room count with a min-heap. int minMeetingRooms(vector<vector<int>>& intervals) { // No meeting requires no room. if (intervals.empty()) { return 0; } // Process meetings in chronological start order. sort(intervals.begin(), intervals.end()); // Store end times for meetings still in progress. priority_queue<int, vector<int>, greater<int>> endTimes; int maximumRooms = 0; // Visit every meeting at the meeting start time. for (vector<int>& interval : intervals) { // Completed meetings release all reusable rooms. while (!endTimes.empty() && endTimes.top() <= interval[0]) { endTimes.pop(); } // The current meeting occupies a room until its end. endTimes.push(interval[1]); // Heap size equals the current occupied room count. int currentRooms = endTimes.size(); maximumRooms = max(maximumRooms, currentRooms); } return maximumRooms; }};// Driver codeint main() { vector<vector<int>> intervals = {{0, 30}, {5, 10}, {15, 20}}; Solution obj; cout << obj.minMeetingRooms(intervals) << endl; return 0;}Complexity Analysis
Time Complexity: O(N log N), where N is the number of meetings, because sorting takes O(N log N) and each meeting end is inserted into and removed from the min-heap at most once.
Space Complexity: O(N), because the min-heap can store up to N meeting end times when all meetings overlap.
Optimal Approach
The min-heap stores individual meeting end times, but we only need to know when the next meeting starts and when the next occupied room becomes free. By sorting all start times and end times separately, these events can be processed directly.
At every step, startIndex points to the earliest unprocessed meeting start, while endIndex points to the earliest unprocessed meeting end. Comparing them tells us whether a new room is required or an existing room can be reused. The maximum number of simultaneously active meetings gives the minimum number of rooms needed.
Algorithm
Handle an empty interval list first, because no meeting requires a room.
Store all meeting start times in one array and all end times in another.
Sort both arrays so events can be processed in chronological order.
Initialize
startIndexandendIndexto0.startIndextracks the earliest meeting that has not started yet.endIndextracks the earliest meeting that has not ended yet.
While unprocessed meeting starts remain, compare
starts[startIndex]withends[endIndex].If
starts[startIndex] < ends[endIndex], a new meeting starts before any current meeting ends.Increase
currentRooms.Update
maximumRooms.Move
startIndexforward.
Otherwise, a meeting ends before or exactly when the next meeting starts.
Decrease
currentRoomsbecause that room becomes available for reuse.Move
endIndexforward.
Return
maximumRooms, because it represents the largest number of meetings running at the same time.
Dry Run
meeting-rooms-ii optimal
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Finds the minimum room count with two pointers. int minMeetingRooms(vector<vector<int>>& intervals) { // No meeting requires no room. if (intervals.empty()) { return 0; } vector<int> starts; vector<int> ends; // Separate event types for independent ordering. for (vector<int>& interval : intervals) { starts.push_back(interval[0]); ends.push_back(interval[1]); } // Place every start and end in chronological order. sort(starts.begin(), starts.end()); sort(ends.begin(), ends.end()); int startIndex = 0; int endIndex = 0; int currentRooms = 0; int maximumRooms = 0; // Process starts until every meeting has begun. while (startIndex < starts.size()) { // An earlier start needs another occupied room. if (starts[startIndex] < ends[endIndex]) { currentRooms++; maximumRooms = max(maximumRooms, currentRooms); startIndex++; } else { // An end on a tie releases a reusable room first. currentRooms--; endIndex++; } } return maximumRooms; }};// Driver codeint main() { vector<vector<int>> intervals = {{0, 30}, {5, 10}, {15, 20}}; Solution obj; cout << obj.minMeetingRooms(intervals) << endl; return 0;}Complexity Analysis
Time Complexity: O(N log N), where N is the number of meetings, because sorting the start and end time arrays takes O(N log N), while the two-pointer sweep takes O(N).
Space Complexity: O(N), because the separate start and end arrays together store 2N values, which simplifies to O(N).
Interview follow-up Questions
Yes. For example, if one meeting is [0,8] and another is [8,10], the first meeting frees the room at time 8. The second meeting can start in the same room at time 8, so only one room is needed.
Be the first to add a comment.