Compute the Union of Two Sorted Interval Lists
GoogleSoftware Engineer · OnsiteLast updated
Merge two sorted lists of disjoint closed intervals into a single sorted list of disjoint intervals in linear time.
Problem Statement
You are given two lists of closed intervals, listA and listB.
Each list is internally pairwise disjoint and sorted in ascending order by start time. That is, within each list, no two intervals overlap or touch, and listA[i][1] < listA[i+1][0].
Return a single list of closed intervals representing the union of listA and listB. The returned list must also be sorted in ascending order and pairwise disjoint. Note that intervals that touch at an endpoint (e.g., [1, 3] and [3, 5]) should be merged into a single continuous interval (e.g., [1, 5]).
Your solution should run in O(n + m) time, where n and m are the lengths of listA and listB respectively.
Function Signature
def interval_union(listA: list[list[int]], listB: list[list[int]]) -> list[list[int]]:
pass
Examples
Example 1
Input:
listA = [[1, 3], [6, 9]]
listB = [[2, 5], [10, 12]]
Output:
[[1, 5], [6, 9], [10, 12]]
Explanation:
- [1, 3] and [2, 5] overlap and merge into [1, 5].
- [6, 9] does not overlap with any remaining interval.
- [10, 12] does not overlap with any remaining interval.
Example 2
Input:
listA = [[1, 4], [8, 10]]
listB = [[4, 6], [7, 8]]
Output:
[[1, 6], [7, 10]]
Explanation:
- [1, 4] and [4, 6] touch at endpoint 4 and merge into [1, 6].
- [7, 8] and [8, 10] touch at endpoint 8 and merge into [7, 10].
Constraints
0 <= len(listA), len(listB) <= 10^5listA[i].length == listB[j].length == 2-10^9 <= start_i <= end_i <= 10^9- Both
listAandlistBare sorted by start coordinate and contain no overlapping or touching intervals internally.
Edge Cases to Consider
- Either or both lists are empty.
- One list entirely contains an interval from the other list.
- Duplicate identical intervals across both lists.
- Intervals touching at a single boundary point.
Hints
Hint 1
Think about how the merge step of Merge Sort combines two sorted sequences using two pointers in linear time.
Hint 2
At each step, take whichever interval starts earlier and compare it against the last interval added to your result.
Hint 3
If the next interval starts before or at the end of the previous interval (curr.start <= prev.end), merge them by updating prev.end = max(prev.end, curr.end); otherwise, append it as a new interval.
Follow-up questions
- How would you adapt your algorithm to handle inputs provided as infinite streaming iterators without buffering entire lists in memory?
- How would you compute the union of k sorted disjoint interval lists instead of two? What is the optimal time complexity?
- How would the logic change if you needed to compute the intersection or difference of the two interval lists instead of the union?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.