题目
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例
c
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
思路
合并重叠区间的一种常见思路是通过排序和遍历来实现:
-
首先,将给定的区间集合按照区间的起始位置进行排序。这样做的目的是为了方便后续的合并操作。
-
初始化一个空的结果集,用于存储合并后的区间。
-
遍历排序后的区间集合。对于每个区间,分为两种情况进行处理:
-
如果当前结果集为空,或者当前区间与结果集中最后一个区间无重叠(即当前区间的起始位置大于结果集中最后一个区间的结束位置),则将当前区间直接加入结果集。
-
否则,说明当前区间与结果集中最后一个区间存在重叠。此时,更新结果集中最后一个区间的结束位置,使其变为当前区间的结束位置和原始结束位置中的较大值。
-
-
遍历结束后,得到的结果集即为合并后的不重叠区间数组。
这种方法的时间复杂度主要取决于排序的时间复杂度,通常为 O(nlogn),其中 n 是区间的个数。遍历区间的时间复杂度为 O(n)。因此,整体的时间复杂度为 O(nlogn)。
Code:
c
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
// 首先按照区间起始位置进行排序
sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
return a[0] < b[0];
});
vector<vector<int>> result;
for (const vector<int>& interval : intervals) {
// 如果当前结果集为空,或者当前区间与结果集中最后一个区间无重叠,则将当前区间加入结果集
if (result.empty() || interval[0] > result.back()[1]) {
result.push_back(interval);
} else {
// 否则,更新结果集中最后一个区间的结束位置
result.back()[1] = max(result.back()[1], interval[1]);
}
}
return result;
}
};