题目描述
给定 n个区间 [li,ri],要求合并所有有交集的区间。注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。例如:[1,3] 和 [2,6]可以合并为一个区间 [1,6]。
输入格式
第一行包含整数 n。接下来 n 行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1≤n≤100000
,
−109≤li≤ri≤109
样例
5
1 2
2 4
5 6
7 8
7 9
输出
3
思路
时间复杂度 $O(n)$
区间问题,先按照左端点或者右段点排序。
1.构想出多个区间
2.按照左端点排序,排序后一定不会出现第二个区间的左端点在第一个区间的左端点前面
3.情况1:两个区间没有交点(ed < a[i].l)直接更新区间 res ++
情况2:两个区间有交点 (ed >= a[i].l)由于有交点,需要合并两个区间为一个区间,
因为第二步我们已经按照左端点排序(也就是已经保证第一个区间的左端点一定小于第二
个区间的左端点)所以这里只需要看是否更新右端点 区间1和区间2的右端点取较大的即可
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
struct node {
int l, r;
};
struct node a[N];
int cmp(struct node t1, struct node t2){
return t1.l < t2.l;
}
int main() {
int n;
cin>>n;
for(int i = 0; i < n; i ++)
cin>>a[i].l>>a[i].r;
sort(a, a + n, cmp);
int res = 0, left = 0x3f3f3f3f, right = -0x3f3f3f3f;
for(int i = 0; i < n; i ++) {
if(a[i].l > right) {
res ++;
left = a[i].l;
right = a[i].r;
} else {
right = a[i].r;
}
}
cout<<res;
return 0;
}