Practice problem
Merge Overlapping Bookings
MediumSolve in Python · graded against 2 sample tests and a hidden test set in your browser · Published
Problem Statement
You're given a list of intervals, each with an integer start and end (start <= end) — think of each one as a booking on a shared resource, occupying every point from its start to its end. Some of these bookings overlap, or even just touch at a single point. Merge every group of overlapping or touching intervals into one interval that spans all of them, and print the resulting intervals, sorted by start, one per line.
Input Format
The input has n + 1 lines:
- Line 1: a single integer n, the number of intervals.
- The next n lines: each contains two integers,
startandend, withstart <= end.
Output Format
Print one line per merged interval, in ascending order of start, each line containing the merged interval's start and end separated by a single space.
Example Walkthrough
Take the first sample: intervals 1-3, 2-6, 8-10, 15-18. Sorted by start, they're already in this
order. Start with 1-3 as the current merged interval. The next interval, 2-6, starts at 2, which is at
or before the current interval's end (3), so it overlaps — extend the current interval's end to
max(3, 6) = 6, making it 1-6. The next interval, 8-10, starts at 8, which is not at or before the
current end (6), so it doesn't overlap — the current interval 1-6 is finished and gets recorded, and
8-10 becomes the new current interval. The last interval, 15-18, starts at 15, well past the current
end (10), so 8-10 is recorded as finished too, and 15-18 becomes current. With no more intervals left,
15-18 is recorded as the final one. The result: 1-6, 8-10, 15-18 — matching the expected output.
Approach
Comparing every interval to every other interval directly is possible but wasteful, and it's easy to miss chains of overlaps (interval A overlapping B, which overlaps C, even if A and C don't directly overlap). Sorting first turns this into a much simpler problem: once the intervals are ordered by start, any interval that's going to overlap with the interval currently being built up can only be the next one in sorted order, or a later one that still starts early enough — so a single left-to-right sweep, comparing only against the current merged interval, is enough to catch every overlap.
After sorting, keep a "current" interval, initialized to the first one. For each subsequent interval in sorted order, compare its start to the current interval's end. If the new interval's start is at or before that end, the two intervals overlap (or touch) — extend the current interval's end to whichever is larger, its own end or the new interval's end (the new interval's end isn't necessarily larger, since it could be entirely contained within the current interval). If instead the new interval's start comes strictly after the current interval's end, there's a gap: the current interval can't grow anymore, so add it to the result list and make the new interval the current one going forward. After the loop finishes, don't forget to add whatever interval is still "current" to the result — there's no later interval left to trigger that step naturally.
Sorting the intervals costs O(n log n), and the single sweep afterward that merges them touches each interval once, in O(n) — so the total time is dominated by the sort.
Common Mistakes
- Using strict
<instead of<=when checking for overlap. The problem defines touching endpoints (like1-4and4-5) as overlapping. A strict<check would treat them as non-overlapping and leave them as two separate intervals,1-4and4-5, instead of merging them into1-5. - Extending the current interval's end to the new interval's end unconditionally. When an overlapping
interval is entirely nested inside the current one — for example, current
1-10followed by2-3— its end (3) is smaller than the current interval's end (10). Overwriting the current end with 3 would incorrectly shrink the merged interval; the end must be updated to the larger of the two. - Forgetting to sort the intervals first. The single-pass merge only works because sorted intervals guarantee that anything still able to overlap the current interval appears next in the scan. Without sorting, an interval far later in the input could overlap an interval processed much earlier, and a simple one-pass sweep would miss that merge entirely.
Sample tests
Sample 1
Input
4 1 3 2 6 8 10 15 18
Expected output
1 6 8 10 15 18
1-3 and 2-6 overlap (2 falls inside 1-3), so they merge into 1-6. 8-10 and 15-18 don't overlap with anything, so they stay as they are.
Sample 2
Input
2 1 4 4 5
Expected output
1 5
1-4 and 4-5 only touch at the single point 4, but touching still counts as overlapping here, so they merge into 1-5.
Your solution
Run tries the first sample. Submit grades against every sample and the hidden tests. Your code is saved in this browser as you go.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.