The Schedule Cleaner
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L4
- Asked in
- Netflix
Problem
You're consolidating playback sessions from a streaming service's event logs, where each session in intervals is a [start, end] timestamp pair that may arrive in any order. Collapse every run of overlapping sessions into one continuous span and return the spans sorted by start time. Sessions that only touch at an endpoint still belong to the same span, so [1, 3] and [3, 5] become [1, 5].
Overlapping sessions. One clean line.
Example
Input:
intervals = [[1,6],[2,6],[8,10],[15,18]]
Output:
[[1,6],[8,10],[15,18]]
Worked solution and explanation
What this really is
Strip the streaming costume and this is range coalescing: turning a pile of possibly-overlapping sessions into the fewest spans that cover exactly the same time. Anyone can write the comparison between two intervals. What separates candidates is two things. Do they put the sessions in start order before comparing anything? And do they treat a span's end as something that only ever grows? Skip the sort and a later session that arrives first hides a real overlap. Overwrite the end instead of keeping the larger one and a short session nested inside a long one, like [2, 4] inside [1, 10], chops the span down to [1, 4].
Walking the merge
Step 1: Sort by start time
Sorting by start guarantees that any session able to overlap the current span is the very next one you visit. That is what turns an all-pairs comparison into a single forward pass.
Step 2: Keep the last span open
Walk the sorted sessions carrying a list of merged spans. The open span is always the last one you appended, so the only thing you ever compare against is merged[-1].
Step 3: Extend or open
The overlap test is start <= merged[-1][1]. It uses <=, not <, so touching endpoints merge. On overlap, push the end out with max(merged[-1][1], end), so a nested session like [2, 4] inside [1, 10] cannot shrink the span. Otherwise the session opens a new span.
The solution
def merge_intervals(intervals):
merged = []
for start, end in sorted(intervals):
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return mergedsorted() builds a new list, so the caller's input is never reordered in place.
Common follow-up questions
- What if the list is already merged and you only need to insert one new interval into it? (Tests the insert-interval variant: a single pass against an already-merged list.)
- What if each session carried a label and you needed to know which originals composed each merged span? (Tests carrying provenance metadata alongside the merge.)
- What if sessions arrived as an unbounded stream instead of a finite list? (Tests maintaining a sorted structure that merges on the fly.)