区间合并
**应用场景:**给定很多个区间,将多个区间进行合并
例题
给定 n n n 个区间 [ l i , r i ] [l_i, r_i] [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如: [ 1 , 3 ] [1,3] [1,3] 和 [ 2 , 6 ] [2,6] [2,6] 可以合并为一个区间 [ 1 , 6 ] [1,6] [1,6]。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1
≤
n
≤
100000
1 \le n \le 100000
1≤n≤100000,
−
1
0
9
≤
l
i
≤
r
i
≤
1
0
9
-10^9 \le l_i \le r_i \le 10^9
−109≤li≤ri≤109
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3
题解:
将多个区间存到vector<pair<int,int>>
中,然后根据所有区间的左坐标进行排序,然后通过从左至右,从小到大依次对相邻的区间进行比较和判断:一共三种情况
对于前面的两种有交集的情况,就可以采取更新区间右坐标进行区间的合并
如果是没有交集,那么就说明当前这个区间无法合并,那么我们就去看接下来的区间,然后对接下来的区间进行重复类似的判断
//核心代码:
void merge(vector<PII>& s)
{
vector<PII> r;
int st=-2e9,en=-2e9;//默认的虚拟区间
sort(s.begin(),s.end());//将所有区间排序
for(auto se:s)
{
if(en<se.first)//两个序列没有交集
{
if(st!=-2e9) r.push_back({st,en});
st=se.first;
en=se.second;
}
else//两个有交集(包括当前枚举的区间是当前维护的区间的子集)
{
en=max(en,se.second);
}
}
if(st!=-2e9)r.push_back({st,en});//最后有一个区间未被统计
s=r;
}