一.题目描述
NC37合并区间:
题目链接:https://www.nowcoder.com/practice/69f4e5b7ad284a478777cb2a17fb5e6atpId=196&&tqId=37071&rp=1&ru=/activity/oj&qru=/ta/job-code-total/question-ranking
给出一组区间,请合并所有重叠的区间,请保证合并后的区间按区间起点升序排列。
二.算法(贪心)
1、将每个区间按左端点从小到大进行排序
2、如图所示,可分3种情况
情况一:当前区间完全被上一区间覆盖,直接跳过
情况二:将当前区间的右端点更新为上一区间的右端点,达到区间延长的效果
情况三:当前区间的左端点严格大于上一区间的右端点,则表示该区间不能合并,更新区间
下面是代码:
#include<algorithm>
bool cmp(Interval a,Interval b){//sort的比较函数
if(a.start==b.start){
return a.end<b.end;
}
return a.start<b.start;
}
class Solution {
public:
vector<Interval> merge(vector<Interval> &intervals) {
vector<Interval> q;
sort(intervals.begin(), intervals.end(),cmp);
int len=intervals.size();
if(len==0) return intervals;
for(int i=1;i<len;i++){
if(intervals[i].start <= intervals[i-1].end){
//区间的合并
intervals[i].start = min(intervals[i-1].start,intervals[i].start);
intervals[i].end = max(intervals[i-1].end,intervals[i].end);
} else{
//将合并好的区间放入
q.push_back(intervals[i-1]);
}
}
q.push_back(intervals[len-1]);//最后一个区间放入
return q;
}
};时间复杂度:O(n) 只需要进行排序后对所有区间进行一次遍历
空间复杂度:O(n) 需要额外开辟空间
优缺点:写起来简单,容易实现
三.算法(排序)
我们用数组ans存储最终的答案。首先,我们将列表中的区间按照左端点升序排序。然后我们将第一个区间加入 merged 数组中,并按顺序依次考虑之后的每个区间:如果当前区间的左端点在数组ans中最后一个区间的右端点之后,那么它们不会重合,我们可以直接将这个区间加入数组ans的末尾;否则,它们重合,我们需要用当前区间的右端点更新数组ans中最后一个区间的右端点,将其置为二者的较大值。
#include<algorithm>
bool cmp(Interval a,Interval b){//sort的比较函数
if(a.start==b.start){
return a.end<b.end;
}
return a.start<b.start;
}
class Solution {
public:
vector<Interval> merge(vector<Interval> &intervals) {
sort(intervals.begin(),intervals.end(),cmp);//排序
vector<Interval>ans;//返回的结果数组
int i = 0,n = intervals.size();
int l,r;
while(i < n){
l = intervals[i].start;//用来表示当前区间左端的指针
r = intervals[i].end; //用来表示当前区间右端的指针
while(i<n-1&&r>=intervals[i+1].start){//合并区间
i++;//指针后移
r=max(r,intervals[i].end);
}
//将当前合并完的区间进行插入
ans.push_back({l,r});
i++;//指针后移
}
return ans;
}
};时间复杂度:O(n) 利用双指针将所有区间遍历
空间复杂度:O(n) 需要额外开辟空间来返回结果
优缺点:时间复杂度相比较算法二低一点,但是写起来麻烦

京公网安备 11010502036488号