Quick Overview

Given interval start times and end times as two parallel lists in arbitrary order, merge every group of overlapping or touching intervals and return the disjoint result sorted by start. It tests interval reasoning, chained overlaps, containment and precise endpoint handling.

Merge Overlapping Time Intervals Given as Parallel Start and End Lists

Company: Walmart Labs

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: easy

Interview Round: Onsite

You receive time intervals as two lists of equal length: `starts[i]` and `ends[i]` are the start time and end time of interval `i`, and the intervals are in no particular order. Merge every group of overlapping intervals into a single interval and return the resulting intervals, none of which overlap. The report describes the task as merging intervals whose times overlap; this version also merges intervals that only touch at an endpoint and fixes the output order, as stated in Rules below. ### Function Signature ```python def merge_time_intervals(starts: list[int], ends: list[int]) -> list[list[int]]: ``` ### Rules - Interval `i` covers every time `t` with `starts[i] <= t <= ends[i]`. - Two intervals overlap when they share at least one time, so `[1, 5]` and `[5, 7]` overlap. Overlap chains: if A overlaps B and B overlaps C, all three belong to the same group even when A and C do not overlap. - Each output interval `[s, e]` covers exactly one maximal group: `s` is the smallest start and `e` the largest end in the group. - Return the output intervals as `[start, end]` pairs sorted by start in ascending order. Because the output intervals are disjoint, this order is unique. ### Constraints - `1 <= len(starts) == len(ends) <= 10^5` - `0 <= starts[i] <= ends[i] <= 10^9` - Intervals may repeat or contain one another. ### Examples **Example 1** ```text Input: starts = [1, 8, 2, 15], ends = [3, 10, 6, 18] Output: [[1, 6], [8, 10], [15, 18]] ``` `[1, 3]` and `[2, 6]` overlap and become `[1, 6]`; `[8, 10]` and `[15, 18]` overlap nothing. **Example 2** ```text Input: starts = [5, 1], ends = [7, 5] Output: [[1, 7]] ``` `[1, 5]` and `[5, 7]` touch at time 5, so they are merged. **Example 3** ```text Input: starts = [9, 1, 2], ends = [9, 10, 3] Output: [[1, 10]] ``` `[2, 3]` and the single point `[9, 9]` both lie inside `[1, 10]`.

Overview: Given interval start times and end times as two parallel lists in arbitrary order, merge every group of overlapping or touching intervals and return the disjoint result sorted by start. It tests interval reasoning, chained overlaps, containment and precise endpoint handling.

Read the full Walmart Labs Software Engineer interview experience this question came from

You receive time intervals as two lists of equal length: `starts[i]` and `ends[i]` are the start time and end time of interval `i`, and the intervals are in no particular order. Merge every group of overlapping intervals into a single interval and return the resulting intervals, none of which overlap. ### Rules - Interval `i` covers every time `t` with `starts[i] <= t <= ends[i]` (both endpoints are included). - Two intervals overlap when they share at least one time, so `[1, 5]` and `[5, 7]` overlap because they touch at time 5. Intervals that share no time, such as `[1, 2]` and `[3, 4]`, do not overlap. - Overlap chains: if A overlaps B and B overlaps C, all three belong to the same group even when A and C do not overlap. - Each output interval `[s, e]` covers exactly one maximal group: `s` is the smallest start and `e` the largest end in the group. - Return the output intervals as `[start, end]` pairs (a list of two-element lists) sorted by start in ascending order. Because the output intervals are disjoint, this order is unique. Every value is at most 10^9, so it never exceeds 2^31 - 1 and fits in a signed 32-bit integer; no sums are needed. ### Constraints - `1 <= len(starts) == len(ends) <= 10^5` - `0 <= starts[i] <= ends[i] <= 10^9` - Intervals may repeat or contain one another, and an interval may be a single point (`starts[i] == ends[i]`). ### Examples **Example 1** ```text Input: starts = [1, 8, 2, 15], ends = [3, 10, 6, 18] Output: [[1, 6], [8, 10], [15, 18]] ``` `[1, 3]` and `[2, 6]` overlap and become `[1, 6]`; `[8, 10]` and `[15, 18]` overlap nothing. **Example 2** ```text Input: starts = [5, 1], ends = [7, 5] Output: [[1, 7]] ``` `[1, 5]` and `[5, 7]` touch at time 5, so they are merged.

Constraints

  • 1 <= len(starts) == len(ends) <= 10^5
  • 0 <= starts[i] <= ends[i] <= 10^9
  • Intervals may repeat or contain one another; an interval may be a single point (starts[i] == ends[i]).

Examples

Input: ([1, 8, 2, 15], [3, 10, 6, 18])

Expected Output: [[1, 6], [8, 10], [15, 18]]

Explanation: Source Example 1: unsorted input; [1, 3] and [2, 6] merge into [1, 6], the other two overlap nothing.

Input: ([5, 1], [7, 5])

Expected Output: [[1, 7]]

Explanation: Source Example 2: [1, 5] and [5, 7] touch at time 5 and merge.

Hints

  1. Both endpoints belong to an interval, so two intervals that only touch at one time still overlap and must end up in the same output interval.
  2. Two intervals that do not overlap each other can still belong to one group through a chain of intervals that overlap pairwise.
  3. A group's end is the largest end among all its members, and an interval can lie entirely inside another, so a member's end can be smaller than its group's end.

Loading coding console...

Show the approach

Approach

Pair each start with its end and sort the pairs by start (ties by end). Sweep the sorted pairs while keeping the last output interval open: if the next start is <= the open interval's end, the two share a time (touching counts because both endpoints are included), so extend the open end to max(open end, next end); otherwise close the open interval and open a new one at the next pair. Invariant: after each step the output holds exactly the merged groups of the pairs seen so far, in ascending start order, and the open interval's end is the largest end in its group. Correctness: every later pair starts at or after the current pair's start, so once a pair starts after the open end, no later pair can reach back into the closed group; inside a group each member starts no later than the running maximum end, so the members form one contiguous chain from the smallest start to the largest end, which also covers transitive chains where the first and last members do not overlap directly. Taking the maximum end rather than the latest end keeps a contained interval from shrinking its group. Edge cases: a single interval or single point returns itself, duplicates collapse into one interval, intervals separated by a gap of one stay apart, and values up to 10^9 fit in 32-bit integers.

Time complexity:
O(n log n)
Space complexity:
O(n)