按左端点排序,遍历时维护当前合并区间,相交则扩右端,否则输出并重开。
OJ: leetcodecn
题目 ID: merge-intervals
难度:普及+/提高
标签:数组排序cpppython
日期: 2026-07-28 22:05
题意
给定区间集合,合并所有重叠区间。
思路
暴力反复合并 O(n²) 效率低。排序后只需一次扫描:按左端点排序,维护当前合并区间。新区间与当前区间相交则扩展右端点,否则输出当前区间并开启新区间。
代码
cpp
/**
* Author by Rainboy
*/
// main.cpp:按左端点排序,遍历合并 O(n log n)。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>> &intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> ans;
for (auto &v : intervals) {
if (ans.empty() || v[0] > ans.back()[1])
ans.push_back(v);
else
ans.back()[1] = max(ans.back()[1], v[1]);
}
return ans;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<vector<int>> a(n, vector<int>(2));
for (int i = 0; i < n; i++)
cin >> a[i][0] >> a[i][1];
auto ans = Solution().merge(a);
for (auto &v : ans)
cout << v[0] << ' ' << v[1] << '\n';
return 0;
}python
#!/usr/bin/env python3
from typing import List
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort()
ans = []
for l, r in intervals:
if not ans or l > ans[-1][1]:
ans.append([l, r])
else:
ans[-1][1] = max(ans[-1][1], r)
return ans
def main() -> None:
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
ans = Solution().merge(a)
for l, r in ans:
print(l, r)
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n log n),排序占主导。
- 空间复杂度:O(log n) 或 O(n),取决于排序实现。
总结
区间合并类的核心预处理是排序。排序后只需要看相邻区间是否相交,不需要反复回溯。该模型也适用于区间交、区间差等变体。