1、定义
-
把所有,有交集的区间合并
-
图解:
2、实现
-
步骤如下:
-
1、首先按照每个区间左端点排序
-
2、扫描 所有区间,进行区间合并
-
上述第二条,可以理解为:拿出一个区间去跟它后面的所有的区间去进行合并(因为我们先拿出左端点去排序,所以不用害怕后面的区间会小于什么的)。
-
-
图解:
· 代码模板:
//将所有存在交集的区间进行合并
void merge(vector<PII> &segs)
{vector<PII> res;sort(segs.begin(),segs.end());int st = -2e9,ed = -2e9;for(auto seg : segs){if(ed < seg.first){if(st!=-2e9) res.push_back({st,ed});st = seg.first,ed = seg.second;}else ed = max(ed,seg.second);}if(st!=-2e9) res.push_back({st,ed});segs = res;
}
3、例题:803. 区间合并 - AcWing题库
-
给定 n个区间 [li ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如: [1,3] 和 [2,6] 可以合并为一个区间 [1,6]。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1≤n≤100000 −10 ^ 9 ≤ li ≤ ri ≤ 10 ^ 9
-
输入样例:
5 1 2 2 4 5 6 7 8 7 9
输出样例:
3
图解:
AC代码(这里给出两种写法):
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<utility>using namespace std;
typedef pair<int,int> PII;
const int N = 100010;
vector<PII> segs;
int n;//区间合并
void merge(vector<PII> &segs)
{vector<PII> res;//用来存储//按区间的左端点来进行排序,然后再按照第二个排序(pair很像)sort(segs.begin(),segs.end());将st(start)和ed(end)初始化为负无穷,确保端点一定在左面int st = -2e9, ed = -2e9;for(auto seg : segs){//如果比较区间的左端点不在当前区间中if(ed < seg.first){//判断一下是否更新 新的当前区间(以防第一次更新)if(st!=-2e9) res.push_back({st,ed});st = seg.first,ed = seg.second;//更新区间,变成当前区间}//如果比较区间的左端点在区间中更新一下最大的右端点else ed = max(ed,seg.second); }//看一下,最后一个元素是否被合并if(st!=-2e9) res.push_back({st,ed});segs = res;
}int main()
{cin >> n;//存入坐标for(int i=0;i<n;i++){int l,r;cin >> l >> r;segs.push_back({l,r});}//区间合并merge(segs);cout << segs.size() << endl;return 0;
}
第二种:
#include<bits/stdc++.h>using namespace std;
typedef pair<int, int> PII;
vector<PII> segs;
int n,res;int main()
{cin >> n;for(int i=0;i<n;i++){int l,r;cin >> l >> r;segs.push_back({l,r});}sort(segs.begin(),segs.end());int ed = segs[0].second;for(int i=1;i<n;i++){if(ed < segs[i].first){res++;ed = segs[i].second;}else ed = max(ed,segs[i].second);}cout << res + 1 << endl;return 0;
}