贪心之区间分组

贪心之区间分组

题目链接:906. 区间分组 - AcWing题库

题目描述:给出几个区间,要求给区间分组,每一组内区间不能重合,求分的的最小组数

算法步骤

1)将所有的区间按左端点从小到大排序

2)从前往后处理每个区间

判断能否将其放入到某个现有的组中 l[i] > Max_r// l[i]是当前区间的左端点,Max_r是组的最右边的右端点

a.如果不存在这样的组,则开新组,然后放入

b.如果存在,则放入,更新Max_r

注意:用小根堆实现,小根堆能动态排序

问题:为什么每次和堆的头部,也就是所有组最大右端点的最小进行比较

因为新区间左端点如果比最小值还要小的话那肯定和其他的也重合了,就要开新组

那为什么比最小值大的话就一定可以加入组呢,就是可以啊,一定可以加入最大右端点最小的那个组

代码实现

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5+10;
int n;
struct Ange{
    int l,r;
}ange[N];
bool cmp(Ange a,Ange b)
{
    return a.l < b.l;
}
int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++ )
    {
        int a,b;
        cin >> a >> b;
        ange[i] = {a,b};
    }
    //按照左端点进行排序
    sort(ange,ange + n,cmp);
    //小根堆写法,堆中存储每个组的最大右端点,堆的大小即为组数
    priority_queue<int,vector<int>,greater<int>> heap;
    //从前往后处理每个区间
    for(int i = 0; i < n; i ++ )
    {
        //如果堆为空或者说新区间和某一组有重合,就开新组,然后放入
        if(heap.empty() || heap.top() >= ange[i].l)
        heap.push(ange[i].r);
        //如果新区间没有和任何一组重合,那就放入一组当中,并更新最小右端点
        else
        {
            heap.pop();
            heap.push(ange[i].r);
        }
        //我疑惑的点在于,为什么这两种操作都将右端点加入堆,那堆的组数是如何定义的呢,
        //发现 第一种情况下没有弹出堆顶元素,说明开了新组,
        //第二种情况弹出堆顶,说明没开新组
        //
    }
    cout << heap.size() << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值