Skip to content

Practice problem

Merge Overlapping Bookings

Medium

Solve 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, start and end, with start <= 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 (like 1-4 and 4-5) as overlapping. A strict < check would treat them as non-overlapping and leave them as two separate intervals, 1-4 and 4-5, instead of merging them into 1-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-10 followed by 2-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.

Ctrl/Cmd+Enter to run

Press Esc then Tab to move keyboard focus out of the code editor.

Ready
Output will appear here after you run your code.

More problems

All practice problems →