【每日算法】LeetCode 56 —— 合并区间(一百四十八)

题目内容

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

示例

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示

1 <= intervals.length <= 10^4
intervals[i].length == 2
0 <= start[i] <= end[i] <= 10^4

题解

本题是将重复区间进行合并,最终得出有效的合并后区间。

首先,看下图:

根据上图,我们把1到5的区间最终分为了两段红色区间。

在解题思路上,我们需要将给出的区间按照左端点进行排序,如果左端点相同则按照右端点排序。

如果下一个区间的左端点小于等于上一个区间的右端点,说明有交集,需要合并以及更新右端点;否则不需要,保存当前的区间即可。

在实现上,我们可以设置一个临时的左右区间判断标识l和r,用于判断合并。

具体,请看代码和注释。

代码

class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
//按左端点排序,如果下一个区间的左端点小于等于上一个区间的右端点,说明有交集,则需要合并,更新右端点;否则不需要,保存当前区间即可。
vector<vector<int>> res;
if(intervals.empty()) return res;

sort(intervals.begin(),intervals.end());//排序

int l = intervals[0][0], r = intervals[0][1];//设置一个临时的l和r,用于更新和合并。
for(int i = 1; i < intervals.size(); i++){
//i可以用1开始,因为第一个区间的左右端点都有了,不需要再次进行遍历
if(intervals[i][0] > r){
//当第二个区间左端点大于第一个区间的右端点,则说明,第一个区间直接可以保存即可
res.push_back({l, r});
l = intervals[i][0], r = intervals[i][1];
}else{
r = max(r,intervals[i][1]);//右端点更新为最大值即可
}
}
res.push_back({l, r});//最后一个区间在更新完l和r之后就没有保存了,需要在for循环外面将其加上。

return res;
}
};
Author: Frederic Niu
Link: https://www.fredericniu.cn/2021/05/22/【每日算法】LeetCode-56-——-合并区间(一百四十八)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
我的公众号