Geek has an array ofnon-overlapping intervals intervals
where intervals[i] = [starti, endi]
represent the start and the end of the ith
event and intervals
is sorted in ascending order by starti
. He wants to add a new interval newInterval= [newStart, newEnd]
where newStart and newEnd represent the start and end of this interval.
Help Geek to insert newInterval into intervals
such that intervals
is still sorted in ascending order by starti
and intervals
still does not have any overlapping intervals (merge overlapping intervals if necessary).
Examples:
Input: intervals = [[1,3], [4,5], [6,7], [8,10]], newInterval = [5,6] Output: [[1,3], [4,7], [8,10]] Explanation: The newInterval [5,6] overlaps with [4,5] and [6,7].
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,9] Output: [[1,2], [3,10], [12,16]] Explanation: The new interval [4,9] overlaps with [3,5],[6,7],[8,10].
Constraints:
1 ≤ intervals.size() ≤ 105
0 ≤ start[i], end[i] ≤ 109
Approach 01:
-
C++
-
Python
#include <vector> #include <algorithm> using namespace std; class Solution { public: vector<vector<int>> insertInterval(vector<vector<int>> &intervals, vector<int> &newInterval) { vector<vector<int>> mergedIntervals; intervals.push_back(newInterval); // Add the new interval to the list sort(intervals.begin(), intervals.end()); // Sort intervals by start time int currentStart = intervals[0][0]; int currentEnd = intervals[0][1]; for (int i = 1; i < intervals.size(); i++) { if (currentEnd >= intervals[i][0]) { // Merge overlapping intervals currentEnd = max(currentEnd, intervals[i][1]); } else { // Add the merged interval to the result mergedIntervals.push_back({currentStart, currentEnd}); currentStart = intervals[i][0]; currentEnd = intervals[i][1]; } } // Add the last interval mergedIntervals.push_back({currentStart, currentEnd}); return mergedIntervals; } };
class Solution: def insertInterval(self, intervals, newInterval): mergedIntervals = [] intervals.append(newInterval) # Add the new interval to the list intervals.sort() # Sort intervals by start time currentStart = intervals[0][0] currentEnd = intervals[0][1] for i in range(1, len(intervals)): if currentEnd >= intervals[i][0]: # Merge overlapping intervals currentEnd = max(currentEnd, intervals[i][1]) else: # Add the merged interval to the result mergedIntervals.append([currentStart, currentEnd]) currentStart = intervals[i][0] currentEnd = intervals[i][1] # Add the last interval mergedIntervals.append([currentStart, currentEnd]) return mergedIntervals
Time Complexity
- Adding the New Interval:
- The new interval is added to the existing intervals list in \(O(1)\).
- Sorting:
- The intervals list, containing \(n + 1\) intervals (where \(n\) is the original size), is sorted based on the start time.
- Sorting takes \(O((n+1) \log(n+1))\), simplified to \(O(n \log n)\).
- Traversal and Merging:
- The sorted intervals are traversed once to merge overlapping intervals.
- This traversal takes \(O(n)\).
- Overall Time Complexity:
The total time complexity is \(O(n \log n)\), dominated by the sorting step.
Space Complexity
- Result Storage:
- The result vector,
mergedIntervals
, stores all intervals after merging. - This requires \(O(n)\) space in the worst case, where no intervals overlap.
- The result vector,
- Sorting Auxiliary Space:
- Sorting the intervals may require \(O(n)\) additional space, depending on the sorting algorithm used (e.g., quicksort or mergesort).
- Other Variables:
- Variables such as
currentStart
,currentEnd
, and loop variables require \(O(1)\) space.
- Variables such as
- Overall Space Complexity:
The total space complexity is \(O(n)\), dominated by the result storage and sorting auxiliary space.