16 合并区间
16.1 合并区间解决方案
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
// 第一步:按照区间的起始值排序
sort(intervals.begin(), intervals.end());
// 初始化一个空的 vector 用于存储合并后的区间
vector<vector<int>> merged;
// 遍历排序后的区间
for (const auto& interval : intervals) {
// 如果 merged 为空,或者当前区间与 merged 中最后一个区间不重叠
if (merged.empty() || merged.back()[1] < interval[0]) {
// 直接将当前区间加入到 merged
merged.push_back(interval);
} else {
// 否则,有重叠,将当前区间与 merged 中最后一个区间合并
merged.back()[1] = max(merged.back()[1], interval[1]);
}
}
// 返回合并后的区间
return merged;
}
};
代码解释:
- 排序:sort(intervals.begin(), intervals.end()); 将区间按照起始值进行排序,使得重叠的区间在相邻位置。
- 合并区间:
- 如果 merged 是空的,或者当前区间的起始值 interval[0] 大于 merged 中最后一个区间的结束值 merged.back()[1],说明当前区间不重叠,可以直接加入 merged。
- 否则,当前区间和 merged 中最后一个区间重叠,此时需要更新 merged 中最后一个区间的结束值为当前区间和最后一个区间结束值的最大值,即 max(merged.back()[1], interval[1])。
- 返回结果:最终 merged 数组中的区间就是合并后的无重叠区间。
16.2 举例说明
假设输入的区间为:
intervals = [[1,3], [2,6], [8,10], [15,18]]
运行过程:
- 排序区间
- 首先,对区间按照起始值 start 进行排序。
- 排序后的结果为:
[[1,3], [2,6], [8,10], [15,18]]
- 因为输入的区间已经是按起始值排好序的,所以在这个例子中排序后结果没有变化。
- 初始化一个空的 merged 数组:merged = []
- 逐一检查每个区间并进行合并操作
- 第一步:
- 当前区间是 [1,3]。
- merged 是空的,所以直接把 [1,3] 加入到 merged 中。
- 结果:merged = [[1,3]]
- 第二步:
- 当前区间是 [2,6]。
- 检查 merged 中的最后一个区间 [1,3],它的结束值是 3
- 当前区间 [2,6] 的起始值是 2,小于等于 3,说明 [2,6] 和 [1,3] 有重叠。
- 因此,需要将 [1,3] 和 [2,6] 合并。合并的结果是 [1, max(3, 6)] = [1,6]
- 更新 merged 的最后一个区间为 [1,6]
- 结果:merged = [[1,6]]
- 第三步:
- 当前区间是 [8,10]。
- 检查 merged 中的最后一个区间 [1,6],它的结束值是 6。
- 当前区间 [8,10] 的起始值是 8,大于 6,说明 [8,10] 和 [1,6] 没有重叠。
- 由于没有重叠,直接把 [8,10] 加入到 merged 中。
- 结果:merged = [[1,6], [8,10]]
- 第四步:
- 当前区间是 [15,18]。
- 检查 merged 中的最后一个区间 [8,10],它的结束值是 10。
- 当前区间 [15,18] 的起始值是 15,大于 10,说明 [15,18] 和 [8,10] 没有重叠。
- 由于没有重叠,直接把 [15,18] 加入到 merged 中。
- 结果:merged = [[1,6], [8,10], [15,18]]
- 第一步:
- 返回结果
- 最终,merged 中的区间就是合并后的区间。
- 返回 merged = [[1,6], [8,10], [15,18]]
关键点说明
- 通过排序,我们确保了每个区间按起始值排列,这样每当我们找到一个新的区间,可以很方便地判断它与前一个区间是否有重叠。
- 如果有重叠,通过更新 merged 中最后一个区间的结束值,我们可以实现合并。
- 如果没有重叠,直接将当前区间添加到 merged 中即可。