Meeting Rooms
Your calendar is given as a list intervals, where intervals[i] = [start, end] describes a meeting that begins at time start and finishes at time end. The meetings are listed in no particular order.
You can only be in one meeting at a time. Return true if you can attend every meeting, meaning no two meetings overlap, and false otherwise.
A meeting that ends at exactly the moment another one starts does not conflict with it: [2,4] and [4,7] can both be attended. An empty calendar is trivially fine.
Example 1
Example 2
Example 3
Constraints
0 <= intervals.length <= 104intervals[i].length == 20 <= start < end <= 106
Pattern Path · Intervals & Greedy · problem 109 of 169
Start simple
Compare every pair of meetings and check whether their time ranges intersect: O(n²) time, O(1) space.
The key idea
Sort the meetings by start time. Now walk through them in order and compare each meeting with the one immediately before it. If the current meeting starts strictly before the previous one ends, the two overlap and the answer is false.
Why are neighbours enough? Suppose no adjacent pair overlaps. Then each meeting ends no later than the next one starts, so the end times increase along with the start times, and every meeting lies entirely before all the meetings after it. Hence no non-adjacent pair can overlap either. Conversely, if any two meetings overlap, some adjacent pair in sorted order does too, so the scan will find it.
Use a strict comparison, start < previous end, so that a meeting starting at the exact moment the previous one finishes is allowed. Sorting dominates the running time.
Complexity
- Time:
O(n log n) - Space:
O(1) extra beyond the sort (O(n) for a sorted copy)
Python
class Solution:
def canAttendMeetings(self, intervals: List[List[int]]) -> bool:
intervals = sorted(intervals) # by start time
for prev, cur in zip(intervals, intervals[1:]):
if cur[0] < prev[1]: # starts before the previous one ends
return False
return True
JavaScript
var canAttendMeetings = function(intervals) {
const sorted = [...intervals].sort((a, b) => a[0] - b[0]); // by start time
for (let i = 1; i < sorted.length; i++) {
if (sorted[i][0] < sorted[i - 1][1]) return false; // starts before the previous one ends
}
return true;
};
What the interviewer is checking
It checks the core interval habit, sort by start and compare neighbours, plus careful handling of touching endpoints.
Mistakes to avoid
- Using
<=and rejecting meetings that only touch at an endpoint. - Forgetting to sort, so only the given (arbitrary) order is checked.
- Sorting by end time but then comparing with the wrong neighbour.
Follow-ups to expect
- How many rooms are needed for all meetings? (Min-heap of end times.)
- Merge all overlapping meetings into blocks. (Sort, extend the current block.)
- Insert a new meeting into a sorted calendar. (Binary search, check neighbours.)
In real software
Calendar apps, room and resource booking systems and job schedulers run exactly this check to detect double bookings before confirming a reservation.