区间合并
**应用场景:**给定很多个区间,将多个区间进行合并
例题
给定 nnn 个区间 [li,ri][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≤1000001 \le n \le 1000001≤n≤100000,
−109≤li≤ri≤109-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;
}