🧠
Sorting + Merge After Insertion
💡 This approach inserts the new interval at the end and then sorts and merges all intervals. It is simpler to implement but less efficient.
Intuition
Add the new interval to the list, sort all intervals by start time, then merge overlapping intervals in one pass.
Algorithm
- Append the new interval to the intervals list.
- Sort the intervals by their start time.
- Initialize a result list with the first interval.
- Iterate through the sorted intervals and merge overlapping intervals.
- Return the merged intervals.
💡 This approach is easier to implement but sorting adds extra time complexity, which might be acceptable depending on constraints.
from typing import List
def insert(intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
intervals.append(newInterval)
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for i in range(1, len(intervals)):
if intervals[i][0] <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], intervals[i][1])
else:
merged.append(intervals[i])
return merged
# Driver code
if __name__ == '__main__':
print(insert([[1,3],[6,9]], [2,5])) # Expected [[1,5],[6,9]]
print(insert([[1,2],[3,5],[6,7],[8,10],[12,16]], [4,8])) # Expected [[1,2],[3,10],[12,16]]
Line Notes
intervals.append(newInterval)Add the new interval to the list before sorting
intervals.sort(key=lambda x: x[0])Sort intervals by start time to prepare for merging
merged = [intervals[0]]Initialize merged list with first interval
if intervals[i][0] <= merged[-1][1]Check if current interval overlaps with last merged interval
merged[-1][1] = max(merged[-1][1], intervals[i][1])Merge intervals by updating end time
else: merged.append(intervals[i])No overlap, add current interval to merged list
return mergedReturn the merged intervals
import java.util.*;
public class InsertInterval {
public static int[][] insert(int[][] intervals, int[] newInterval) {
int n = intervals.length;
int[][] allIntervals = new int[n + 1][];
System.arraycopy(intervals, 0, allIntervals, 0, n);
allIntervals[n] = newInterval;
Arrays.sort(allIntervals, Comparator.comparingInt(a -> a[0]));
List<int[]> merged = new ArrayList<>();
merged.add(allIntervals[0]);
for (int i = 1; i < allIntervals.length; i++) {
int[] last = merged.get(merged.size() - 1);
if (allIntervals[i][0] <= last[1]) {
last[1] = Math.max(last[1], allIntervals[i][1]);
} else {
merged.add(allIntervals[i]);
}
}
return merged.toArray(new int[merged.size()][]);
}
public static void main(String[] args) {
int[][] res1 = insert(new int[][]{{1,3},{6,9}}, new int[]{2,5});
System.out.println(Arrays.deepToString(res1)); // [[1,5],[6,9]]
int[][] res2 = insert(new int[][]{{1,2},{3,5},{6,7},{8,10},{12,16}}, new int[]{4,8});
System.out.println(Arrays.deepToString(res2)); // [[1,2],[3,10],[12,16]]
}
}
Line Notes
int[][] allIntervals = new int[n + 1][];Create new array to hold original plus new interval
System.arraycopy(intervals, 0, allIntervals, 0, n);Copy original intervals into new array
allIntervals[n] = newInterval;Add new interval at the end
Arrays.sort(allIntervals, Comparator.comparingInt(a -> a[0]));Sort all intervals by start time
List<int[]> merged = new ArrayList<>();Initialize list to hold merged intervals
if (allIntervals[i][0] <= last[1])Check overlap with last merged interval
last[1] = Math.max(last[1], allIntervals[i][1]);Merge intervals by updating end time
merged.add(allIntervals[i]);Add non-overlapping interval
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
intervals.push_back(newInterval);
sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
return a[0] < b[0];
});
vector<vector<int>> merged;
merged.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] <= merged.back()[1]) {
merged.back()[1] = max(merged.back()[1], intervals[i][1]);
} else {
merged.push_back(intervals[i]);
}
}
return merged;
}
int main() {
vector<vector<int>> intervals1 = {{1,3},{6,9}};
vector<int> newInterval1 = {2,5};
vector<vector<int>> res1 = insert(intervals1, newInterval1);
for (auto &iv : res1) cout << '[' << iv[0] << ',' << iv[1] << "] ";
cout << endl; // Expected [1,5] [6,9]
vector<vector<int>> intervals2 = {{1,2},{3,5},{6,7},{8,10},{12,16}};
vector<int> newInterval2 = {4,8};
vector<vector<int>> res2 = insert(intervals2, newInterval2);
for (auto &iv : res2) cout << '[' << iv[0] << ',' << iv[1] << "] ";
cout << endl; // Expected [1,2] [3,10] [12,16]
return 0;
}
Line Notes
intervals.push_back(newInterval);Add new interval to the list
sort(intervals.begin(), intervals.end(), ...Sort intervals by start time
vector<vector<int>> merged;Initialize vector to hold merged intervals
merged.push_back(intervals[0]);Start merged list with first interval
if (intervals[i][0] <= merged.back()[1])Check if current interval overlaps with last merged
merged.back()[1] = max(merged.back()[1], intervals[i][1]);Merge intervals by updating end time
merged.push_back(intervals[i]);Add non-overlapping interval
function insert(intervals, newInterval) {
intervals.push(newInterval);
intervals.sort((a, b) => a[0] - b[0]);
const merged = [intervals[0]];
for (let i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= merged[merged.length - 1][1]) {
merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], intervals[i][1]);
} else {
merged.push(intervals[i]);
}
}
return merged;
}
console.log(insert([[1,3],[6,9]], [2,5])); // [[1,5],[6,9]]
console.log(insert([[1,2],[3,5],[6,7],[8,10],[12,16]], [4,8])); // [[1,2],[3,10],[12,16]]
Line Notes
intervals.push(newInterval);Add new interval to intervals array
intervals.sort((a, b) => a[0] - b[0]);Sort intervals by start time
const merged = [intervals[0]];Initialize merged array with first interval
if (intervals[i][0] <= merged[merged.length - 1][1])Check overlap with last merged interval
merged[merged.length - 1][1] = Math.max(...)Merge intervals by updating end time
merged.push(intervals[i]);Add non-overlapping interval
Sorting the intervals dominates the time complexity. Merging afterwards is O(n).
💡 For n=10,000, sorting takes about 10,000 * log2(10,000) ≈ 132,877 operations, slower than linear.
Interview Verdict: Accepted but less optimal
This approach works but is less efficient due to sorting. Good for quick implementation if constraints allow.