必须先排序,因vector中区间顺序任意,不排序无法线性判断重叠;应按左端点升序排序,左端点相同时右端点降序;再单次遍历,用current维护当前合并区间,通过next[0]≤current[1]判断是否合并。

合并重叠区间前必须排序
不排序直接遍历,std::vector 里的区间顺序是任意的,无法保证左端点递增,也就没法线性判断是否重叠。比如 [5,8] 和 [1,3] 看似不重叠,但若它们在容器中相邻,你根本不会意识到 [1,3] 其实该和后面的 [2,6] 合并。
正确做法是先按左端点升序排序,左端点相同时再按右端点降序(可选,但能简化逻辑):
std::sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) {
return a[0] b[1]);
});
用单次遍历 + 当前合并段变量完成合并
排序后,只需维护一个当前正在构建的区间 current,逐个检查后续区间是否能合并进去。关键判断是:next[0] —— 即下一个区间的左端点是否 ≤ 当前区间的右端点。
合并时只更新右端点:current[1] = std::max(current[1], next[1]);不能直接赋值,因为可能出现 [1,10] 和 [2,5] 这种包含关系。
常见错误包括:
- 误用
而非判断重叠(导致 [1,4] 和 [4,6] 被当成不重叠) - 忘记更新
current[1],而是直接覆盖成next[1] - 把
push_back(current)放在循环内部每次迭代都执行,而不是等真正断开时才推入结果
注意 vector 元素类型与边界条件
输入通常是 std::vector<:vector>> 或 std::vector<:pair>>。前者更常见但访问略啰嗦(intervals[i][0]),后者用 .first/.second 更清晰,且内存更紧凑。
边界情况要手动处理:
- 输入为空:
if (intervals.empty()) return {}; - 输入只有一个区间:排序后仍需推入结果,不能跳过
- 所有区间都不重叠:每个都要单独 push
别依赖“循环末尾自动 push”,必须在遍历结束后显式 result.push_back(current),否则最后一个合并段会丢失。
性能与稳定性提醒
排序是 O(n log n),遍历是 O(n),整体时间复杂度由排序主导。如果输入已知有序(比如来自扫描线算法输出),可跳过排序,但必须确认——很多“看似有序”的数据其实因浮点误差或插入顺序导致左端点微小错乱。
使用 int 是安全的,但如果区间端点可能超 INT_MAX,得换成 long long 并确保比较逻辑一致。另外,不要在合并过程中修改原 intervals 容器(如 erase),这会破坏迭代器有效性,也无必要。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











