The Overlap
A hard Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- hard
- Seniority
- L5
Problem
Maintenance entries in windows are [start, end] minute ranges filed in whatever order they were logged, and any that overlap or touch describe one continuous outage the on-call engineer has to report. Collapse them into those outages, earliest first.
Overlapping windows are one outage. Collapse them into the truth.
Example 1
Input:
windows = [[1,3],[2,6],[8,10],[15,18]]
Output:
[[1,6],[8,10],[15,18]]
Example 2
Input:
windows = [[1,4],[4,5]]
Output:
[[1,5]]
Worked solution and explanation
What this really is
Strip the costume and this is a one-dimensional coverage merge: a pile of time ranges that secretly describe fewer, longer ranges. The trap is reaching for O(n^2) pairwise overlap checks, comparing every window against every other. One sort kills that. Once the windows are ordered by start, every range that belongs with the current one sits immediately to its right, so a single greedy pass merges everything. Get the merge condition wrong and you split [1,4] and [4,5] into two outages when they are really one unbroken window.
Walking it
Step 1: Sort by start time
Sorting by start time is the whole game: it guarantees that any window overlapping the current one is the very next element, so you never have to look backward. Without it you are stuck comparing all pairs.
Step 2: Seed the result
Seed the result with the first sorted window. Everything after this is a decision: does the next window join this one, or start a fresh one.
Step 3: Extend or append
For each remaining window, if its start is at or before the last merged end it overlaps or touches, so set the last end to max(last_end, end). The max is critical: a contained window like [2,5] inside [1,10] must not pull the end backward. If it starts after the last end, the gap is genuine, so append it.
The solution
def merge_windows(windows):
if not windows:
return []
ordered = sorted(windows, key=lambda w: w[0])
merged = [ordered[0]]
for start, end in ordered[1:]:
last_start, last_end = merged[-1]
if start <= last_end:
merged[-1] = [last_start, max(last_end, end)]
else:
merged.append([start, end])
return mergedOne sort, one pass; max(last_end, end) protects contained windows.
Common follow-up questions
- How would you insert one new window into an already-merged list cheaply? (Tests binary search for the insertion point and local re-merging instead of a full re-sort.)
- What changes if windows arrive in a stream rather than all at once? (Tests maintaining a sorted structure such as a balanced BST for online merging.)
- How would you find the moment of maximum concurrent overlap? (Tests the sweep-line idea with separate start and end events.)