Max_r 表示当前组中所有区间右端点的最大值
L[i] 表示当前需要判断的区间的左端点
方法思路:
1. 将所有区间按左端点从小到大排序
2. 从前往后处理每个区间,判断能否将其放到某个现有的组中,L[i] > Max_r ?
- 1 如果不存在这样的组,则开新组,然后再将其放进去;
-
2 如果存在这样的组,将其放进去,并更新当前组的Max_r
使用小根堆动态维护最小值
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5 + 10;
int n;
struct Range {
int l, r;
bool operator < (const Range &W) const {
return l < W.l; //重载小于号
}
} range[N];
int main (){
scanf("%d", &n);
int l, r;
for (int i = 0; i < n; i ++) {
scanf("%d%d", &l, &r);
range[i] = {l, r};
}
sort(range, range + n);
priority_queue <int, vector<int>, greater<int>> heap; // 小根堆 维护所有区间右端点的最大值
for (int i = 0; i < n; i ++) {
auto r = range[i];
if (heap.empty() || r.l <= heap.top()) heap.push(r.r); //堆空,则一个组都没有;堆顶(所有最大值Max_r中的最小值)L[i] <= Max_r创建新的组
else { // 有重叠有交集,找到Max_r最小的组,将r.r当前区间右端点加进去最小Max_r的组中(堆顶),做法:删除堆顶,因为此时的堆顶已经不是Max_r,r.r才是当前组的Max_r
auto t = heap.top(); // 没有用到,但是习惯上一般将堆顶先保存下来,再删除
heap.pop();
heap.push(r.r);
}
}
printf("%d\n", heap.size()); //组数就是当前堆中元素数量
return 0;
}