mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 21:22:43 +00:00
docs(content): add detailed interval explanation with overlap condition and merging pattern
This commit is contained in:
1 parent
9c2aaf5969
commit
d9dc90e433
1 file changed
+60
@@ -3,3 +3,63 @@ title: Intervals
|
||||
description: 'Ranges with a start and an end are sorted, and then merged, counted, or scheduled.'
|
||||
hidden: true
|
||||
---
|
||||
|
||||
An interval is a pair `[start, end]` marking a stretch on a line:
|
||||
- the minutes a meeting occupies
|
||||
- the range a task runs
|
||||
- the span a sensor was active
|
||||
|
||||
**What interval problems ask you?**
|
||||
|
||||
- Do any two collide?
|
||||
- What does the timeline look like once you merge everything that touches?
|
||||
- How many rooms do you need so no two meetings share one?
|
||||
|
||||
:::tip
|
||||
Every one of those questions reduces to a single primitive: deciding whether two intervals overlap, and if they do, what part they share. Once that primitive is clear, the rest of the pattern is bookkeeping.
|
||||
:::
|
||||
|
||||
## When two intervals overlap
|
||||
|
||||
It is easier to state when two intervals do not overlap. Interval a sits entirely before interval `b` when a finishes before b begins, that is `a.end < b.start`. By symmetry they also miss each other when `b` ends before a starts. If neither of those holds, the intervals overlap.
|
||||
|
||||

|
||||
|
||||
Negating `a.end < b.start` or `b.end < a.start` gives the positive test directly: two intervals overlap exactly when `a.start <= b.end` and `b.start <= a.end`. That pair of comparisons is the whole overlap check.
|
||||
|
||||
## The Shared Region
|
||||
|
||||
When two intervals do overlap, the part they share is itself an interval. Its start is the later of the two starts, and its end is the earlier of the two ends: `[max(a.start, b.start), min(a.end, b.end)]`. The overlap begins only once both intervals have started, and it ends the moment either one stops.
|
||||
|
||||

|
||||
|
||||
## Sort by Start first
|
||||
|
||||
Left unsorted, checking a list of intervals means comparing every pair, which is `O(n^2)`. Sorting the intervals by start time removes that cost. Once the list is in start order, any interval can only overlap ones that come after it and begin before it ends, so a single left-to-right pass is enough to merge, count, or detect collisions.
|
||||
|
||||
Sorting by start is the standard first line of almost every interval solution, and the problems below all lean on it.
|
||||
|
||||
That gives the template every interval problem in this section builds on: sort by start, then sweep once, comparing each interval against the last one you kept.
|
||||
|
||||
|
||||
```python
|
||||
# Time: O(n log n)
|
||||
# Space: O(n)
|
||||
def interval_pattern(intervals):
|
||||
# 1. Sort by start time
|
||||
intervals.sort(key=lambda x: x[0])
|
||||
result = []
|
||||
for start, end in intervals:
|
||||
# 2. Overlap with the last kept interval? end >= next start
|
||||
if result and start <= result[-1][1]:
|
||||
# Merge: extend the end of the last interval
|
||||
result[-1][1] = max(result[-1][1], end)
|
||||
else:
|
||||
# 3. No overlap: keep this interval as-is
|
||||
result.append([start, end])
|
||||
return result
|
||||
```
|
||||
|
||||
### Footnote
|
||||
|
||||
The positive overlap test comes straight from De Morgan's law. Negating `(a.end < b.start)` or `(b.end < a.start)` gives `(a.end >= b.start)` and `(b.end >= a.start)`, which is the `a.start <= b.end` and `b.start <= a.end` condition rewritten.
|
||||
Reference in new issue
Block a user