【题目】
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 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] 可被视为重叠区间。
提示:
- 1 <= intervals.length <=
- intervals[i].length == 2
- 0 <= <= <=
【题目解析】
方法解析
-
排序:首先按照区间的起始位置对所有区间进行排序。这使得我们可以通过一次遍历来合并所有重叠的区间。
-
合并区间:遍历排序后的区间列表,对于每个区间:
- 如果当前区间的起始位置大于结果数组中最后一个区间的结束位置,则不重叠,将当前区间添加到结果数组中。
- 否则,它们重叠,我们需要合并这两个区间。将结果数组中最后一个区间的结束位置更新为当前区间和最后一个区间结束位置的较大值。
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
if not intervals:
return []
# 按起始位置排序
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for i in range(1, len(intervals)):
# 如果当前区间的起始位置大于merged中最后一个区间的结束位置
if intervals[i][0] > merged[-1][1]:
merged.append(intervals[i])
else:
# 合并区间
merged[-1][1] = max(merged[-1][1], intervals[i][1])
return merged
执行效率
【总结】
适用问题类型
合并区间问题适用于需要对一系列时间或数值范围进行合并处理的情况,特别是当这些范围存在重叠时。这种类型的问题在日程管理、资源分配、网络带宽优化等多个领域都有广泛应用。
解决算法:排序加贪心
-
算法描述:首先按照区间起始位置排序,然后遍历排序后的区间列表,贪心地合并所有重叠的区间。
-
算法特点:
- 高效处理重叠区间:通过排序预处理,使得所有可能重叠的区间都相邻,便于合并。
- 简洁直观:算法逻辑清晰,易于理解和实现。
- 广泛适用:不仅适用于简单的区间合并,也可以扩展到更复杂的区间操作问题。
时间复杂度与空间复杂度
- 时间复杂度:
O(nlogn),主要时间开销来自于排序步骤,其中n是区间的数量。遍历并合并区间的过程时间复杂度为O(n)。 - 空间复杂度:
O(logn)或O(n),取决于所使用的排序算法。如果使用原地排序(如快速排序),则为O(logn);如果排序算法需要额外空间(如归并排序),则为O(n)。
实践意义
- 解决实际问题:合并区间算法在处理涉及时间段、数值范围等的实际问题时非常有用,能够有效减少不必要的复杂度和资源消耗。
- 算法优化思维:学习和实现合并区间算法能够帮助开发者培养面对问题时寻找高效解决方案的思维,特别是在处理涉及排序和贪心选择的问题时。
- 编程技能提升:通过实现合并区间问题的解法,开发者可以加深对排序、贪心算法以及区间操作等算法技巧的理解和应用,提升编程能力。
总体来说,合并区间问题不仅是一个经典的算法题目,其解法也具有广泛的实用价值,能够帮助我们更高效地处理实际中的区间合并问题。通过学习这一问题的算法,我们可以将其应用于解决更广泛的问题场景。