LeetCode hot100:056 合并区间:高效算法解析
问题描述:
以数组 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] 可被视为重叠区间。
示例 3:
输入:intervals = [[4,7],[1,4]]
输出:[[1,7]]
解释:区间 [1,4] 和 [4,7] 可被视为重叠区间。
解决方法:
采用排序加线性扫描法进行实现,算法设计思路:
- 排序预处理:将所有区间按照起始位置的大小进行排序;
- 合并重叠区间:遍历排序后的区间,逐个判断是否与结果中最后一个区间有重叠;
- 更新结果:如果区间重叠,则合并,不重叠直接添加。
class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:if not intervals:return []#intervals.sort()intervals.sort(key = lambda x:x[0]) #按照单个区间的首元素进行排序result = []for interval in intervals:if not result or interval[0] > result[-1][1]: #结果集为空 或 结果集末尾集合的尾元素小于当前区间的首元素result.append(interval)else:result[-1][1] = max(interval[1] , result[-1][1]) #合并区间 选择较大的尾元素作为当前集合的endreturn result复杂度分析:
- 时间复杂度:O(n log n),主要是排序的时间复杂度
- 空间复杂度:O(log n),其中n为区间的数量
问题详解:
1、执行过程演示:

2、排序的意义:通过按起始位置排序,我们可以确保所有可能重叠的区间都相邻排列,从而可以线性扫描完成合并。
3、重叠判断条件:两个区间 [a, b] 和 [c, d] 重叠的条件是 c <= b。
4、合并策略:当两个区间重叠时,新的结束位置取两者的最大值。
5、lambda匿名函数:
- lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式;
- 特点:lambda 函数是匿名的,它们没有函数名称,只能通过赋值给变量或作为参数传递给其他函数来使用;
- 语法格式:
lambda arguments: expressionarguments是参数列表,可以包含零个或多个参数,但必须在冒号(
:)前指定,expression是一个表达式,用于计算并返回函数的结果。 示例:
numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, numbers)) print(squared) # 输出: [1, 4, 9, 16, 25]
6、关于排序:直接使用 intervals.sort() 也是可行,由于在 Python 中,当对列表的列表进行排序时:默认行为:首先比较第一个元素,如果第一个元素相同,再比较第二个元素。
总结:
合并区间问题是一个经典的贪心算法应用,核心思想可以总结为:
排序预处理:将子区间按起始位置排序,使得重叠的区间相邻排列;
贪心合并:线性扫描,遇到重叠区间立即合并;
边界处理:注意处理各种特殊情况,如空输入、单点区间等。
该问题的解决方案体现了"局部最优选择导致全局最优解"的贪心思想。
