持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情
一、题目
描述:
给出一组区间,请合并所有重叠的区间。
请保证合并后的区间按区间起点升序排列。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Interval {
int start;
int end;
Interval() : start(0), end(0) {}
Interval(int s, int e) : start(s), end(e) {}
};
vector<Interval> merge(vector<Interval> &intervals) {
}
int main(int, char*[])
{
vector<Interval> intervals = {{10,30},{20,60},{80,100},{150,180}};
vector<Interval> result = merge(intervals);
for(size_t i = 0; i < result.size(); ++i){
cout << i + 1 << "\tstart:" << result.at(i).start << "\tend:" << result.at(i).end << endl;
}
return 0;
}
二、分析
由题意可知,要将区间进行合并,就需要判断出区间之间的包含关系,但是由于区间有两个端点,要同时兼顾两个端点,实现起来很难,所以需要降低难度。
如何才能只判断一个端点呢?
只需要保证一个端点一定不会出现包含,要想达到这个效果,也很简单,只需按照一个端点进行排序,只要一个端点是呈降序或增序,再按照顺序遍历,就不会出现向左包含。
排序之后,只需要再判断下一个区间的小端点是否包含在前一个区间之中,如果是,则是属于包含关系,合并即可。
三、模拟
- [10,30]
- [10,30] [20,60] 20被包含在10-30之间,所以可以合并,此时需要判断合并后的大端点是哪一个?因为我们是判断了小端点,但是大端点是不确定的。
- [10,60]
- [10,60] [80,100] 80大于60,不包含
- [80,100] [150,180] 150大于100,不包含
四、实现
vector<Interval> merge(vector<Interval> &intervals) {
vector<Interval> result;
if(intervals.empty()) return result;
sort(intervals.begin(), intervals.end(), [](Interval& i1, Interval& i2){return i1.start < i2.start;});
result.push_back(intervals.front());
for(size_t i = 1; i < intervals.size(); ++i){
if(intervals.at(i).start <= result.back().end){
if(intervals.at(i).end > result.back().end){
result.back().end = intervals.at(i).end;
}
}else{
result.push_back(intervals.at(i));
}
}
return result;
}
五、结言
找到问题所在,尽可能简化问题,才是解决问题之道。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!