给定 n 个区间 (l_i,r_i),要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3]和[2,6]可以合并为一个区间[1,6]。
输入格式
第一行包含整数n。
接下来n行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
(1≤n≤100000,)
(−10^9≤l_i≤r_i≤10^9)
两种方法,都是先按照区间左端点排序,然后从左到右去看当前区间和下一个区间之间的包含关系来确定是更新当前区间还是合并成新的区间。
复杂度:(O(nlogn + n) = O(nlogn))
模板1
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define PII pair<int, int>
int n;
vector<PII> segs;
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 st = -2e9, ed = -2e9;
vector<PII> res;
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});
cout << res.size() << endl;
return 0;
}
模板2
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define PII pair<int, int>
int n;
vector<PII> segs;
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 cnt = 1;
for(int i = 1, j = 0; i < segs.size(); i ++)
if(segs[j].second >= segs[i].first)
segs[j].second = max(segs[j].second, segs[i].second);
else{
cnt ++;
j = i;
}
cout << min(cnt, segs.size()) << endl; // 此处为了防止segs为空
return 0;
}