You are given an array of non-overlapping intervals intervals where intervals[i] = [ s t a r t i , e n d i start_i, end_i starti,endi] represent the start and the end of the i t h i^{th} ith interval and intervals is sorted in ascending order by s t a r t i start_i starti. You are also given an interval newInterval = [start, end] that represents the start and end of another interval.
Insert newInterval into intervals such that intervals is still sorted in ascending order by s t a r t i start_i starti and intervals still does not have any overlapping intervals (merge overlapping intervals if necessary).
Return intervals after the insertion.
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
From: LeetCode
Link: 57. Insert Interval
The main idea behind the code is to break down the insertion process into three primary segments:
1. Before the new interval:
In this phase, the algorithm checks all intervals that are entirely before the newInterval. This is determined by checking if the end of the current interval is less than the start of the newInterval. All such intervals are directly added to the result because they won’t overlap with the newInterval.
2. Merging overlapping intervals with the new interval:
In this phase, the algorithm checks for any intervals that overlap with the newInterval. An overlap is determined if the start of the current interval is less than or equal to the end of the newInterval. For each overlapping interval, the start of the merged interval becomes the minimum of the current interval’s start and the newInterval’s start. Similarly, the end of the merged interval becomes the maximum of the current interval’s end and the newInterval’s end.
3. After the new interval:
Post merging, all intervals that come entirely after the merged newInterval are added to the result as they are, because they won’t have any overlap with the newInterval.
In the end, the function updates the returnSize to indicate the number of intervals in the result, and returnColumnSizes is updated to indicate the size of each interval (which is always 2). The result is then returned.
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* newInterval, int newIntervalSize, int* returnSize, int** returnColumnSizes){
// Initializations
int** res = (int**)malloc(sizeof(int*) * (intervalsSize + 1)); // +1 in case we don't merge and just insert the new interval
int* colSizes = (int*)malloc(sizeof(int) * (intervalsSize + 1));
int index = 0, resIndex = 0;
// Before the new interval
while(index < intervalsSize && intervals[index][1] < newInterval[0]){
res[resIndex] = intervals[index];
colSizes[resIndex] = 2;
resIndex++;
index++;
}
// Merge overlapping intervals with new interval
while(index < intervalsSize && intervals[index][0] <= newInterval[1]){
newInterval[0] = fmin(newInterval[0], intervals[index][0]);
newInterval[1] = fmax(newInterval[1], intervals[index][1]);
index++;
}
// Add the merged new interval
int* mergedInterval = (int*)malloc(sizeof(int) * 2);
mergedInterval[0] = newInterval[0];
mergedInterval[1] = newInterval[1];
res[resIndex] = mergedInterval;
colSizes[resIndex] = 2;
resIndex++;
// After the new interval
while(index < intervalsSize){
res[resIndex] = intervals[index];
colSizes[resIndex] = 2;
resIndex++;
index++;
}
// Set return sizes
*returnSize = resIndex;
*returnColumnSizes = colSizes;
return res;
}