区间合并的朴素做法
- 时间复杂度O(n2)
- 第一层循环遍历遍历区间,然后第二层循环去查找区间看能否合并然后更新,时间复杂度太高了
区间合并的贪心做法
- 左端点为关键字然后从小到大排序
- 当前区间和下一个区间的关系有三种:

- 核心板子代码
inline vector<PII> merge(vector<PII>& ref) {
sort(ref.begin(), ref.end());
int st = -INF, ed = -INF;
vector<PII> res;
for (int i = 0; i < ref.size(); ++i) {
if (ed < ref[i].first) {
if (ed != -INF)res.push_back({ st,ed });
st = ref[i].first, ed = ref[i].second;
}
ed = max(ref[i].second, ed);
}
if (st != INF) res.push_back({ st, ed });
return res;
}
- 板子题链接: https://www.acwing.com/problem/content/805/
- 板子题代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> PII;
int arr[N];
vector<PII> vec;
inline int max(const int& a, const int& b) {
return a > b ? a : b;
}
inline vector<PII> merge(vector<PII>& ref) {
sort(ref.begin(), ref.end());
int st = -INF, ed = -INF;
vector<PII> res;
for (int i = 0; i < ref.size(); ++i) {
if (ed < ref[i].first) {
if (ed != -INF)res.push_back({ st,ed });
st = ref[i].first, ed = ref[i].second;
}
ed = max(ref[i].second, ed);
}
if (st != INF) res.push_back({ st, ed });
return res;
}
int main(void) {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int l, r;
cin >> l >> r;
vec.push_back({ l,r });
}
auto res = merge(vec);
cout << res.size() << endl;
return 0;
}
补充
- 跟区间有关的问题很多都是用贪心,先左端点或者右端点排序,或者双关键字排序
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix