Linear Scan
Intuition
Since the intervals are already sorted and non-overlapping, we can solve this in a single pass. We iterate through the intervals and classify each one into three groups: intervals that come entirely before the new interval, intervals that overlap with the new interval, and intervals that come entirely after. Non-overlapping intervals before are added directly. Overlapping intervals are merged with the new interval by taking the minimum start and maximum end. Non-overlapping intervals after are added directly. This clean three-phase approach handles all cases elegantly.
Algorithm
- Initialize an empty result list.
- Iterate through `intervals`. For each interval:
- After the loop, if `newInterval` has not been added, append it to the result.
- Return the result.
O(n)SpaceO(n)Code (C++ · Java · Python · Go)
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> result;
int i = 0;
int n = intervals.size();
// Add all intervals that come before newInterval
while (i < n && intervals[i][1] < newInterval[0]) {
result.push_back(intervals[i]);
i++;
}
// Merge overlapping intervals with newInterval
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++;
}
result.push_back(newInterval);
// Add all intervals that come after newInterval
while (i < n) {
result.push_back(intervals[i]);
i++;
}
return result;
}
};class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> result = new ArrayList<>();
int i = 0;
int n = intervals.length;
// Add all intervals that come before newInterval
while (i < n && intervals[i][1] < newInterval[0]) {
result.add(intervals[i]);
i++;
}
// Merge overlapping intervals with newInterval
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++;
}
result.add(newInterval);
// Add all intervals that come after newInterval
while (i < n) {
result.add(intervals[i]);
i++;
}
return result.toArray(new int[result.size()][]);
}
}def insert(intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
result = []
i = 0
n = len(intervals)
# Add all intervals that come before newInterval
while i < n and intervals[i][1] < newInterval[0]:
result.append(intervals[i])
i += 1
# Merge overlapping intervals with newInterval
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
result.append(newInterval)
# Add all intervals that come after newInterval
while i < n:
result.append(intervals[i])
i += 1
return resultfunc insert(intervals [][]int, newInterval []int) [][]int {
result := [][]int{}
i := 0
n := len(intervals)
// Add all intervals that come before newInterval
for i < n && intervals[i][1] < newInterval[0] {
result = append(result, intervals[i])
i++
}
// Merge overlapping intervals with newInterval
for i < n && intervals[i][0] <= newInterval[1] {
if intervals[i][0] < newInterval[0] {
newInterval[0] = intervals[i][0]
}
if intervals[i][1] > newInterval[1] {
newInterval[1] = intervals[i][1]
}
i++
}
result = append(result, newInterval)
// Add all intervals that come after newInterval
for i < n {
result = append(result, intervals[i])
i++
}
return result
}