56. 合并区间
题目描述
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例2:
输入: intervals = [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
提示:
- i n t e r v a l s [ i ] [ 0 ] ≤ i n t e r v a l s [ i ] [ 1 ] intervals[i][0] \le intervals[i][1] intervals[i][0]≤intervals[i][1]
题解:
把区间按照 左端点从小到大 排序,左端点相同的话,右端点从大到小排序。
这样排序可以保证能够合并的区间是相邻的。
从前往后遍历数组,使用两个指针 s
和 e
分别记录 i
前面一个区间的左右端点:
-
若
seg[i][0] <= e
,说明当前区间和前面的区间有交集,合并它们, 也就是更新e = max( e, seg[i][1] )
-
若
seg[i][0] > e
,说明当前区间和前面的区间没有交集,需要把前面的区间保存到结果中,重新设置s = seg[i][0], e = seg[i][1]
-
遍历完数组后,把最后的
s
和e
表示的区间保存到数组中
时间复杂度: O ( n l o n g n ) O(nlongn) O(nlongn)
额外空间复杂度: O ( n ) O(n) O(n)
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
int n = intervals.size();
if ( n < 2 ) return intervals;
sort( intervals.begin(), intervals.end() );
vector<vector<int>> ret;
int s = intervals[0][0], e = intervals[0][1];
for ( int i = 1; i < n; ++i ) {
if ( intervals[i][0] <= e ) {
e = max( e, intervals[i][1] );
} else {
ret.push_back({s, e});
s = intervals[i][0];
e = intervals[i][1];
}
}
ret.push_back({s, e});
return ret;
}
};
/*
时间:12ms,击败:99.93%
内存:13.8MB,击败:94.50%
*/