Insert Interval
Insert a new interval into a sorted non-overlapping list, merging as needed — single linear pass.
3 min read
intervals
Problem#
Given a list of non-overlapping intervals sorted by start, insert newInterval and merge any overlaps. Return the resulting list.
Examples#
intervals = [[1,3],[6,9]], newInterval = [2,5]→[[1,5],[6,9]]intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]→[[1,2],[3,10],[12,16]]
Constraints#
0 <= intervals.length <= 10^4.
Approach#
Three-phase linear walk: (1) push every interval ending before newInterval starts; (2) merge every overlapping interval into newInterval; (3) push the merged interval and everything after.
Solution#
class Solution {public: vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int> newInterval) { vector<vector<int>> ans; int i = 0, n = intervals.size(); while (i < n && intervals[i][1] < newInterval[0]) ans.push_back(intervals[i++]); while (i < n && intervals[i][0] <= newInterval[1]) { newInterval[0] = min(newInterval[0], intervals[i][0]); newInterval[1] = max(newInterval[1], intervals[i][1]); ++i; } ans.push_back(newInterval); while (i < n) ans.push_back(intervals[i++]); return ans; }};func insert(intervals [][]int, newInterval []int) [][]int { minI := func(a, b int) int { if a < b { return a } return b } maxI := func(a, b int) int { if a > b { return a } return b } ans := [][]int{} i, n := 0, len(intervals) for i < n && intervals[i][1] < newInterval[0] { ans = append(ans, intervals[i]) i++ } for i < n && intervals[i][0] <= newInterval[1] { newInterval[0] = minI(newInterval[0], intervals[i][0]) newInterval[1] = maxI(newInterval[1], intervals[i][1]) i++ } ans = append(ans, newInterval) for i < n { ans = append(ans, intervals[i]) i++ } return ans}from typing import List
class Solution: def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: ans: List[List[int]] = [] i, n = 0, len(intervals) while i < n and intervals[i][1] < newInterval[0]: ans.append(intervals[i]) i += 1 while i < n and intervals[i][0] <= newInterval[1]: newInterval[0] = min(newInterval[0], intervals[i][0]) newInterval[1] = max(newInterval[1], intervals[i][1]) i += 1 ans.append(newInterval) while i < n: ans.append(intervals[i]) i += 1 return ansfunction insert(intervals, newInterval) { const ans = []; let i = 0; const n = intervals.length; while (i < n && intervals[i][1] < newInterval[0]) { ans.push(intervals[i++]); } while (i < n && intervals[i][0] <= newInterval[1]) { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); i++; } ans.push(newInterval); while (i < n) { ans.push(intervals[i++]); } return ans;}class Solution { public int[][] insert(int[][] intervals, int[] newInterval) { List<int[]> ans = new ArrayList<>(); int i = 0, n = intervals.length; while (i < n && intervals[i][1] < newInterval[0]) ans.add(intervals[i++]); while (i < n && intervals[i][0] <= newInterval[1]) { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); i++; } ans.add(newInterval); while (i < n) ans.add(intervals[i++]); return ans.toArray(new int[0][]); }}function insert(intervals: number[][], newInterval: number[]): number[][] { const ans: number[][] = []; let i = 0; const n = intervals.length; while (i < n && intervals[i][1] < newInterval[0]) { ans.push(intervals[i++]); } while (i < n && intervals[i][0] <= newInterval[1]) { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); i++; } ans.push(newInterval); while (i < n) { ans.push(intervals[i++]); } return ans;}Editorial#
Sorted, non-overlapping input means the three phases (before / overlapping / after) are contiguous in the original list. The middle phase folds every overlapper into newInterval, growing it monotonically. Total O(n).
Complexity#
- Time: O(n).
- Space: O(n).
Concept revision#
Related#