Merge Overlapping Intervals
Company: J.P. Morgan
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
## Merge Overlapping Intervals
You are given an array `intervals` where each element `intervals[i] = [start_i, end_i]` represents a closed interval on the number line. Merge all intervals that **overlap** (including those that merely touch at an endpoint) and return an array of the resulting non-overlapping intervals that together cover exactly the same set of points as the input.
Two intervals `[a, b]` and `[c, d]` overlap when `c <= b` (assuming `a <= c`); for example `[1, 4]` and `[4, 5]` overlap and merge into `[1, 5]`.
### Example 1
```
Input: intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
Output: [[1, 6], [8, 10], [15, 18]]
```
`[1, 3]` and `[2, 6]` overlap and merge into `[1, 6]`.
### Example 2
```
Input: intervals = [[1, 4], [4, 5]]
Output: [[1, 5]]
```
The intervals touch at `4`, so they merge.
### Example 3
```
Input: intervals = [[1, 4], [0, 4]]
Output: [[0, 4]]
```
### Constraints
- `1 <= intervals.length <= 10^4`
- `intervals[i].length == 2`
- `0 <= start_i <= end_i <= 10^6`
- The input is **not** guaranteed to be sorted.
### Required Output
Return a list of merged intervals. The output should be sorted in ascending order by start value, and no two returned intervals may overlap.
Quick Answer: This question tests practical array manipulation and sorting skills by requiring candidates to consolidate overlapping numeric intervals into a minimal set. It evaluates algorithmic reasoning around interval overlap conditions and is a staple coding problem used to assess proficiency with greedy techniques and sorted data processing.
You are given an array `intervals` where each element `intervals[i] = [start_i, end_i]` represents a closed interval on the number line. Merge all intervals that **overlap** (including those that merely touch at an endpoint) and return an array of the resulting non-overlapping intervals that together cover exactly the same set of points as the input.
Two intervals `[a, b]` and `[c, d]` overlap when `c <= b` (assuming `a <= c`); for example `[1, 4]` and `[4, 5]` overlap and merge into `[1, 5]`.
### Example 1
```
Input: intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
Output: [[1, 6], [8, 10], [15, 18]]
```
`[1, 3]` and `[2, 6]` overlap and merge into `[1, 6]`.
### Example 2
```
Input: intervals = [[1, 4], [4, 5]]
Output: [[1, 5]]
```
The intervals touch at `4`, so they merge.
### Example 3
```
Input: intervals = [[1, 4], [0, 4]]
Output: [[0, 4]]
```
The output must be sorted in ascending order by start value, and no two returned intervals may overlap. The input is **not** guaranteed to be sorted.
Constraints
- 1 <= intervals.length <= 10^4
- intervals[i].length == 2
- 0 <= start_i <= end_i <= 10^6
- The input is not guaranteed to be sorted.
Examples
Input: [[1, 3], [2, 6], [8, 10], [15, 18]]
Expected Output: [[1, 6], [8, 10], [15, 18]]
Explanation: [1,3] and [2,6] overlap (2 <= 3) and merge into [1,6]; the rest are disjoint.
Input: [[1, 4], [4, 5]]
Expected Output: [[1, 5]]
Explanation: The intervals touch at 4, which counts as overlapping, so they merge into [1,5].
Input: [[1, 4], [0, 4]]
Expected Output: [[0, 4]]
Explanation: After sorting, [0,4] and [1,4] overlap and merge; the result is sorted by start.
Input: [[1, 4], [2, 3]]
Expected Output: [[1, 4]]
Explanation: [2,3] is fully contained in [1,4]; the merged end stays max(4, 3) = 4.
Input: [[5, 6]]
Expected Output: [[5, 6]]
Explanation: A single interval cannot overlap anything and is returned unchanged.
Input: [[1, 2], [3, 4], [5, 6]]
Expected Output: [[1, 2], [3, 4], [5, 6]]
Explanation: All intervals are disjoint (gaps between them), so none merge.
Input: [[6, 8], [1, 9], [2, 4], [4, 7]]
Expected Output: [[1, 9]]
Explanation: Unsorted input. After sorting, [1,9] swallows all the others, leaving a single interval.
Hints
- Sort the intervals by their start value first. After sorting, any interval that overlaps a later one must overlap the one immediately before it.
- Sweep left to right, keeping the last merged interval. Treat intervals as overlapping when the next start is <= the current end (touching endpoints count as overlapping).
- When the next interval overlaps, extend the current interval's end to max(current_end, next_end); otherwise start a new merged interval.