Given a collection of intervals, represented as pairs of integers [start, end]
, where start
denotes the start time of the interval and end
denotes the end time of the interval. Merge overlapping intervals to create non-overlapping intervals.
Table of Contents
Example:
Input:
intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
Output:
[[1, 6], [8, 10], [15, 18]]
Explanation: In the input, the intervals [1, 3]
and [2, 6]
overlap, so they can be merged into [1, 6]
. The remaining intervals [8, 10]
and [15, 18]
are already non-overlapping. Thus, the merged intervals are [[1, 6], [8, 10], [15, 18]]
.
Merge Intervals Solution in C++:
#include <iostream>
#include <vector>
#include <algorithm>
// Function to merge overlapping intervals
std::vector<std::vector<int>> mergeIntervals(std::vector<std::vector<int>>& intervals) {
if (intervals.empty()) return {};
// Sort the intervals based on their start time in ascending order
std::sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) {
return a[0] < b[0];
});
std::vector<std::vector<int>> mergedIntervals;
mergedIntervals.push_back(intervals[0]);
// Iterate through the sorted intervals
for (int i = 1; i < intervals.size(); ++i) {
int currStart = intervals[i][0];
int currEnd = intervals[i][1];
// If the current interval overlaps with the last merged interval, merge them
if (currStart <= mergedIntervals.back()[1]) {
mergedIntervals.back()[1] = std::max(mergedIntervals.back()[1], currEnd);
} else {
// If the current interval does not overlap, add it to the merged intervals
mergedIntervals.push_back({currStart, currEnd});
}
}
return mergedIntervals;
}
int main() {
std::vector<std::vector<int>> intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
std::vector<std::vector<int>> result = mergeIntervals(intervals);
std::cout << "Merged Intervals:\n";
for (const auto& interval : result) {
std::cout << "[" << interval[0] << ", " << interval[1] << "] ";
}
std::cout << std::endl;
return 0;
}
Merge Intervals Explanation:
- The
mergeIntervals
function takes a reference to a vector of vectorsintervals
. - We first handle the edge case where the
intervals
vector is empty. If it’s empty, there are no intervals to merge, so we return an empty vector. - We sort the
intervals
vector based on their start time in ascending order using a custom comparator. This helps us find overlapping intervals efficiently. - We create a new vector
mergedIntervals
to store the merged intervals. We initialize it with the first interval from the sortedintervals
vector. - We iterate through the sorted intervals starting from the second interval. For each interval, we compare its start time
currStart
with the end time of the last interval inmergedIntervals
, denoted asmergedIntervals.back()[1]
. IfcurrStart
is less than or equal to the end time of the last interval, it means the current interval overlaps with the last merged interval. In this case, we update the end time of the last merged interval to be the maximum of the current end timecurrEnd
and the existing end time. This effectively merges the two overlapping intervals. - If the current interval does not overlap with the last merged interval, we add it to the
mergedIntervals
. - After processing all intervals, the
mergedIntervals
vector will contain non-overlapping intervals.
Time Complexity:
The time complexity of this solution is O(n log n), where n
is the number of intervals in the input vector intervals
. The main factor in the time complexity is the sorting step, which takes O(n log n) time using std::sort
.
Space Complexity:
The space complexity of this solution is O(n), where n
is the number of intervals in the input vector intervals
. This is because we create a new vector mergedIntervals
to store the merged intervals, and in the worst case, it can contain n
intervals if all intervals are non-overlapping.