算法学习笔记(9)——区间合并

区间合并

区间合并问题也是一个贪心问题,由于比较常用所以单独拿出来。区间合并的解决方法是,把所有区间按照左端点 l 从小到大排序,然后维护一个当前正在处理的区间 [st,ed],如果遍历到区间和维护的区间有交集,就合并(能合则合),没有交集的时候,当前维护的区间就变成这个遍历到的区间。

这里按照左端点排序好之后,每次遍历到的区间和当前区间 [st,ed] 只会有三种状态:

img

情况(1)是 led 并且 red,这个时候可以和当前区间合并,合并后的当前区间就是 [st,ed]

情况(2)是 led 并且 r>ed,这个时候可以和当前区间合并,合并后的当前区间就是 [st,r]

情况(3)是 l>ed,这个时候不能和当前区间合并,当前区间要从 [st,ed] 变成新的 [l,r]

所以只要在 led 的时候进行区间合并,合并就是对 edr 取一个较大值作为合并后的当前区间的右端点。在 l>ed 的时候没法合并,而是把维护的当前区间变成这个正在遍历的区间就可以了。

题目链接:AcWing 803. 区间合并

本题中我们用pair<int, int>类型存储每一个区间,题目所给的范围是从 1e91e9,所以我们选择一个不在此范围内的数字进行初始化,便于我们在第一次遍历区间左右端点时进行判断。

每次在判断新来的区间左端点 seg.first 大于待合并区间的右端点 ed 时,说明前一区间合并完毕,加入最终的答案集合中。如果枚举的是第一个区间,则不需要加入集合,修改当前的起始点即可。

在枚举完所有区间之后还要进行一次判断,此时如果当前维护的区间 [l,r] 还没有被加入答案集合中,也就是所有区间都合并为了一个区间的情况,我们还需要把这个区间加入到最终答案集合中去。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

vector<PII> segs;

void merge(vector<PII> &segs)
{
    vector<PII> res;
    sort(segs.begin(), segs.end());
    int st = -2e9, ed = -2e9;
    for (auto seg : segs) {
        if (seg.first > ed) {
            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});
    segs = res;
}

int main()
{
    int n;
    cin >> n;
    
    while (n -- ) {
        int l, r;
        cin >> l >> r;
        segs.push_back({l, r});
    }
    
    merge(segs);
    
    cout << segs.size() << endl;
    
    return 0;
}
posted @   S!no  阅读(273)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示