算法学习笔记(9)——区间合并
区间合并
区间合并问题也是一个贪心问题,由于比较常用所以单独拿出来。区间合并的解决方法是,把所有区间按照左端点 从小到大排序,然后维护一个当前正在处理的区间 ,如果遍历到区间和维护的区间有交集,就合并(能合则合),没有交集的时候,当前维护的区间就变成这个遍历到的区间。
这里按照左端点排序好之后,每次遍历到的区间和当前区间 只会有三种状态:
情况(1)是 并且 ,这个时候可以和当前区间合并,合并后的当前区间就是 。
情况(2)是 并且 ,这个时候可以和当前区间合并,合并后的当前区间就是 。
情况(3)是 ,这个时候不能和当前区间合并,当前区间要从 变成新的 。
所以只要在 的时候进行区间合并,合并就是对 和 取一个较大值作为合并后的当前区间的右端点。在 的时候没法合并,而是把维护的当前区间变成这个正在遍历的区间就可以了。
本题中我们用pair<int, int>
类型存储每一个区间,题目所给的范围是从 到 ,所以我们选择一个不在此范围内的数字进行初始化,便于我们在第一次遍历区间左右端点时进行判断。
每次在判断新来的区间左端点 大于待合并区间的右端点 时,说明前一区间合并完毕,加入最终的答案集合中。如果枚举的是第一个区间,则不需要加入集合,修改当前的起始点即可。
在枚举完所有区间之后还要进行一次判断,此时如果当前维护的区间 还没有被加入答案集合中,也就是所有区间都合并为了一个区间的情况,我们还需要把这个区间加入到最终答案集合中去。
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具