题目
为什么说是行为模拟题?
我们平常自己如何合并存在交集的区间?
应该是先在坐标轴上把相应的区间范围画出来,
而这道题就是通过计算机模拟你这个人类的行为。
解题分析
既然是模拟我们解题的行为,那么我们可以对程序作以下两步设计:
- 对各个区间根据左区间大小进行排序,此时我们就只需要判断每个相邻区间的R和L的关系便可以确认两个区间是否有交集。
- 确认有交集后我们需要确认合并区间的右边界R,这个时候只需要对两个区间的右区间的大小进行判断即可,大的成为右区间。
解题代码
一步排序到位–易理解型
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
//以区间左端点进行排序
sort(intervals.begin(),intervals.end());
//创建二维数组用于存储新的答案
vector<vector<int>>merge;
//遍历原数组,通过比较前一个R和后一个L来判断是否合并为同一个区间进入mrege
for(int i = 0;i<intervals.size();i++){
int L=intervals[i][0],R=intervals[i][1];
//如果merge数组为空,或者是与前面的区间无交集,则新建区间加入merge数组
if(!merge.size()||merge.back()[1]<L){
merge.push_back({L,R});
}else{//如果有交集,判断右边界谁更大,大的包含小的,更新区间的右边界为大的那个。
merge.back()[1] = max(merge.back()[1],R);
}
}
return merge;
}
};
这个更像是模拟找规律,有兴趣可以画个坐标图看看
老哥死磕型–分开排序型
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
int n = intervals.size();
vector<vector<int>> res;
vector<int> starts, ends;
for (int i = 0; i < n; ++i) {
starts.push_back(intervals[i][0]);
ends.push_back(intervals[i][1]);
}
//把左右区间分开排序,后面操作实际和之前是一样的,只不过左右区间进行了分开,
//这样只能通过扫描什么时候L区间大于上一个区间的R区间,此时开始更新,只不过,直接对区间的操作更容易理解
sort(starts.begin(), starts.end());
sort(ends.begin(), ends.end());
for (int i = 0, j = 0; i < n; ++i) {
if (i == n - 1 || starts[i + 1] > ends[i]) {
res.push_back({starts[j], ends[i]});
j = i + 1;
}
}
return res;
}
};