leetcode:56. 合并区间
题目
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
解答 & 代码
区间问题两个技巧:
- 排序:此题是区间合并问题,只需按照起点升序排序即可(若起点相同,终点大小的顺序无所谓)
- 画图:画出两个区间所有可能的相对位置,分情况讨论
class Solution {
private:
// 自定义排序函数
static bool cmp(vector<int> a, vector<int> b)
{
return a[0] < b[0] || (a[0] == b[0] && a[1] > b[1]);
}
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
// 1. 排序:对于区间合并问题,按起点升序排序即可(若起点相同,终点大小的顺序无所谓)
sort(intervals.begin(), intervals.end(), cmp);
// 2. 合并区间
vector<vector<int>> result;
result.push_back(intervals[0]); // 先将第一个区间压入结果数组
for(int i = 1; i < intervals.size(); ++i)
{
// case 1 & 2:如果当前区间被结果数组最后一个区间覆盖 or
// 当前区间和结果数组最后一个区间相交
// 则,更新结果数组最后一个区间的右边界
if(intervals[i][0] <= result.back()[1])
result.back()[1] = max(result.back()[1], intervals[i][1]);
// case 3:如果当前区间和结果数组最后一个区间无交集
// 则,将当前区间存入结果数组
else
result.push_back(intervals[i]);
}
return result;
}
};
复杂度分析:设原区间个数为 N
- 时间复杂度 O(NlogN):排序时间复杂度
- 空间复杂度 O(1):结果数组不计
执行结果:
执行结果:通过
执行用时:28 ms, 在所有 C++ 提交中击败了 74.53% 的用户
内存消耗:18.4 MB, 在所有 C++ 提交中击败了 69.71% 的用户