Skip to content

Insert Interval

You are given an array of non-overlapping intervals intervals where intervals[i] = [starti, endi] represent the start and end of the ith interval. You are also given a new interval newInterval = [newStart, newEnd] that may overlap with some of the existing intervals.

Insert newInterval into intervals such that intervals is still sorted and non-overlapping (merge overlapping intervals as necessary). Return the resulting array of intervals.

intervalsnewIntervalOutputExplanation
[[1,2],[3,5],[6,9]][2,5][[1,5],[6,9]][2,5] overlaps with [1,2] and [3,5], merge to [1,5]
[[1,5]][0,0][[0,0],[1,5]][0,0] doesn’t overlap, add before
[[1,5]][5,7][[1,7]][5,7] overlaps at boundary, merge
[[1,2],[3,5],[6,9]][10,11][[1,2],[3,5],[6,9],[10,11]][10,11] doesn’t overlap, append
  • 0 <= intervals.length <= 10^4
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 10^5
  • newInterval.length == 2
  • 0 <= newStart <= newEnd <= 10^5
  • intervals is sorted by start and does not contain overlapping intervals
ApproachTimeSpaceNotes
Greedy Three-PhaseO(n)O(n)Single pass through intervals; merge during iteration
Iterative MergeO(n)O(n)Explicit three phases; clearer logic
Section titled “Approach 1: Greedy Three-Phase (Recommended)”
★ Recommended

Divide the problem into three phases:

  1. Add all intervals that end before newInterval starts.
  2. Merge all overlapping intervals with newInterval.
  3. Add remaining intervals that start after the merged interval ends.

This is efficient because the input is pre-sorted and non-overlapping.

⏱ Time O(n) Single scan through intervals 💾 Space O(n) Result list storage

Input: intervals = [[1,2],[3,5],[6,9]], newInterval = [2,5]

PhaseActionResult
1Add [1,2] (ends before 2)[[1,2]]
2Merge [2,5] with [3,5] → [2,5][[1,2], [2,5]]
3Merge [2,5] with [6,9]? No (6 > 5)[[1,2], [2,5]]
FinalAdd [6,9][[1,2], [2,5], [6,9]]
function insert(intervals, newInterval):
result = []
i = 0
newStart, newEnd = newInterval
// Phase 1: Add non-overlapping intervals before
while i < len(intervals) and intervals[i][1] < newStart:
result.append(intervals[i])
i += 1
// Phase 2: Merge overlapping intervals
while i < len(intervals) and intervals[i][0] <= newEnd:
newStart = min(newStart, intervals[i][0])
newEnd = max(newEnd, intervals[i][1])
i += 1
result.append([newStart, newEnd])
// Phase 3: Add remaining intervals
while i < len(intervals):
result.append(intervals[i])
i += 1
return result
insert_interval_greedy.py
from typing import List
def insert(intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
"""Greedy approach: O(n) time, O(n) space"""
result, i, new_start, new_end = [], 0, newInterval[0], newInterval[1]
while i < len(intervals) and intervals[i][1] < new_start:
result.append(intervals[i])
i += 1
while i < len(intervals) and intervals[i][0] <= new_end:
new_start = min(new_start, intervals[i][0])
new_end = max(new_end, intervals[i][1])
i += 1
result.append([new_start, new_end])
while i < len(intervals):
result.append(intervals[i])
i += 1
return result
✓ Simple

Identical algorithm to Approach 1 but written with explicit three-phase structure. More verbose but clarifies the three distinct merge phases.

⏱ Time O(n) Three single-pass loops 💾 Space O(n)
function insert(intervals, newInterval):
result = []
i = 0
newStart, newEnd = newInterval
// Phase 1: Add intervals ending before new interval starts
while i < len(intervals) and intervals[i][1] < newStart:
result.append(intervals[i])
i += 1
// Phase 2: Merge overlapping intervals
while i < len(intervals) and intervals[i][0] <= newEnd:
newStart = min(newStart, intervals[i][0])
newEnd = max(newEnd, intervals[i][1])
i += 1
result.append([newStart, newEnd])
// Phase 3: Append remaining non-overlapping intervals
while i < len(intervals):
result.append(intervals[i])
i += 1
return result
insert_interval_iterative.py
from typing import List
def insert(intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
"""Iterative approach: O(n) time, O(n) space"""
result = []
for interval in intervals:
if interval[1] < newInterval[0]:
result.append(interval)
elif interval[0] > newInterval[1]:
result.append(newInterval)
newInterval = interval
else:
newInterval[0] = min(newInterval[0], interval[0])
newInterval[1] = max(newInterval[1], interval[1])
result.append(newInterval)
return result
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
insert_interval_space_optimized.py
"""
Solution for Insert Interval
"""
def solve():
"""Implementation for approach 3 of Insert Interval"""
pass
if __name__ == "__main__":
print("Solution ready")