—
i
Given a list of meeting time intervals, determine whether a person can attend all of them — i.e., no two meetings overlap. Sort by start time, then a single pass checking adjacent pairs is all it takes.
You are given a list of meeting intervals, each as [start, end]. Return true if a person can attend every meeting without any two overlapping. For example, [[0,30],[5,10],[15,20]] → false because [0,30] and [5,10] collide. But [[7,10],[2,4]] → true — after sorting, [2,4] ends before [7,10] starts.
prev.end > curr.start), there's a conflict. You never need to compare non-adjacent meetings — sorting collapses O(n²) checks to O(n).intervals[i-1][1] (end of previous) with intervals[i][0] (start of current).prev.end > curr.start, they overlap — return false immediately.true.prev.end > curr.start (strict greater-than), not >=. Back-to-back meetings like [0,10],[10,20] are fine — one ends exactly when the next starts, which is not an overlap. Using >= incorrectly rejects them.The sort is in-place so space is O(1)auxiliary (ignoring the recursion stack of the sort). You can't beat O(n log n) here because you need to distinguish any ordering of intervals — information-theoretic lower bound matches the sort.
3 meetings by start time. Sorted order lets us compare only adjacent pairs.function canAttendMeetings(intervals: number[][]): boolean {
intervals.sort((a, b) => a[0] - b[0]);
for (let i = 1; i < intervals.length; i++) {
const prev = intervals[i - 1];
const curr = intervals[i];
if (prev[1] > curr[0]) return false; // overlap: prev ends after curr starts
}
return true;
}intervals.sort((a, b) => a[0] - b[0])puts meetings in chronological order. After this, any overlap must involve adjacent meetings — that's the key invariant the rest of the algorithm relies on.1, compare prev[1] (the end of the meeting we just passed) against curr[0](the start of the next). If the previous meeting hasn't ended yet when the next one begins, they conflict.prev[1] > curr[0] is the only check needed. Strict > because touching boundaries (e.g. 10 and 10) are allowed — the person walks out of one room and into the next.true.a.start instead of a[0]).prev.end + buffer > curr.start.true (vacuously no conflicts). A single meeting returns true. All meetings identical returns false.| "can attend all meetings" / "no overlap" | sort by start + adjacent-pair scan |
| detect overlap between intervals | prev.end > curr.start (strict) |
| "how many rooms needed" | Meeting Rooms II — min-heap of end times |
| "merge / insert / remove intervals" | same sort-then-sweep skeleton |
function canAttendMeetings(intervals: number[][]): boolean {
intervals.sort((a, b) => a[0] - b[0]);
for (let i = 1; i < intervals.length; i++) {
const prev = intervals[i - 1];
const curr = intervals[i];
if (prev[1] > curr[0]) return false;
}
return true;
}prev = [s1, e1] and curr = [s2, e2]?[[0,30],[5,10],[15,20]]. After sorting by start, which pair triggers the overlap?[[7,10],[2,4]] return true or false?