Merge Intervals medium
Problem Statement
Given an array of intervals
where intervals[i] = [starti, endi]
, merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.
Example 1
Input: intervals = [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Example 2
Input: intervals = [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considered overlapping.
Steps
-
Sort the intervals: Sort the intervals based on their start times. This ensures that we process overlapping intervals consecutively.
-
Initialize the merged intervals: Create a vector to store the merged intervals. Add the first interval from the sorted list to the
merged
vector. -
Iterate and merge: Iterate through the sorted intervals starting from the second interval. For each interval:
- If the current interval overlaps with the last interval in
merged
, merge them by updating the end time of the last interval inmerged
to the maximum of the current interval's end time and the last interval's end time. - If the current interval does not overlap, add it to the
merged
vector.
- If the current interval overlaps with the last interval in
-
Return the merged intervals: Return the
merged
vector containing the non-overlapping intervals.
Explanation
The key idea is to sort the intervals by their start times. This allows us to process them sequentially and efficiently identify overlapping intervals. Overlapping intervals will always be adjacent after sorting. We merge them by taking the maximum of their end times. This guarantees that we cover all the points within the overlapping intervals.
Code
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if (intervals.empty()) return {};
// Sort intervals by start time
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]); // Add the first interval
for (size_t i = 1; i < intervals.size(); ++i) {
vector<int>& current = intervals[i];
vector<int>& last = merged.back();
// Check for overlap: If current start is <= last end
if (current[0] <= last[1]) {
// Merge by updating the end of the last interval
last[1] = max(last[1], current[1]);
} else {
// No overlap, add the current interval
merged.push_back(current);
}
}
return merged;
}
Complexity
- Time Complexity: O(N log N), dominated by the sorting step. The iteration through the sorted intervals takes linear time.
- Space Complexity: O(N) in the worst case, if no intervals are merged (all intervals are non-overlapping). The
merged
vector could potentially store all the input intervals. In the best case (all intervals merge), space complexity is O(1).