题目
给出一个区间的集合,请合并所有重叠的区间。
示例 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] 可被视为重叠区间。
注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。
提示:
intervals[i][0] <= intervals[i][1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
题意理解
- intervals[i][0] <= intervals[i][1]
同一区间的上限和下限可以相等,不是上限严格大于下限。 - 重叠区间
对于两个区间,只要一个区间下限大于或等于另一个区间上限,就可以被重叠,此时由于第一条理解,可能存在前者的上限并不一定要比后者的上限严格大,可以相等。
- 重叠区间举例
- [[1,4],[4,5]] 恰好符合重叠条件(或者说相交)
- [[1,5],[4,4]] 完全重叠(或者说子集)
解题
题目要求返回重叠后的区间情况,形式和 intervals 相同, n× 2 矩阵列表。
为了保证所有区间重叠情况均被考虑在内,需要遍历整个 intervals 列表,与结果列表比对,是否存在重叠,根据不同情况更新结果列表中的区间范围,直到遍历结束。
最好是将 intervals 按照每个区间下限从小到大的顺序原地排序,便于快速比较 intervals 内两区间的重叠情况,避免重复考虑某一区间,于是采取快速排序的方法。
- 结果列表为空时,直接将第一个区间添加进去;
- 比较 intervals 列表区间的下限与此时结果列表里最后一个区间的上限:
- 严格大,表明完全不重叠,直接添加 interval 当前区间,作为结果列表最新区间;
- 小于等于情况,符合重叠区间条件,子集或者相交情况,结果列表此时区间的下限已经确定,上限则由两者中的上限最大值来决定。
时间复杂度和空间复杂度主要由快速排序决定,分别是 O(nlogn)和 O(logn),n 表示列表长度
提交代码
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x:x[0])
res = []
for i in range(len(intervals)):
if not res or intervals[i][0] > res[-1][1]:
res.append(intervals[i])
else:
res[-1][1] = max(res[-1][1],intervals[i][1])
return res
结果
总结
- 解题思路较为清晰,首先快速排序,再遍历每个区间与结果取件相比较;
- 比较情况需要归类分析,将同一步骤操作的情况合并考虑,简化代码;
- 完成情况较好。