返回
LeetCode HOT 100:合并区间背后的微妙细节
前端
2023-12-16 13:13:35
前言
LeetCode 作为算法题练习平台,其 HOT 100 题目无疑是备受关注的经典之作。本篇文章将聚焦于其中的“合并区间”这一中等难度的题目,带领大家深入剖析其背后蕴藏的微妙细节。
题目概述
“合并区间”问题如下:
给定一个由区间组成的列表,每个区间表示一个时间段的开始和结束时间。合并所有重叠的区间,返回合并后的区间列表。
例如:
输入:[[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
贪心算法
贪心算法是一种逐步做出局部最优选择,期望最终获得全局最优解的算法。对于本题而言,贪心算法的思路为:
- 对区间按照开始时间排序。
- 遍历排序后的区间列表,将每个区间与上一个区间比较:
- 如果两个区间重叠,则合并这两个区间。
- 否则,将当前区间添加到结果列表中。
以下为 Python 实现:
def merge_intervals(intervals):
# 对区间按开始时间排序
intervals.sort(key=lambda x: x[0])
merged_intervals = []
for interval in intervals:
# 如果结果列表为空或当前区间与上一个区间不重叠
if not merged_intervals or merged_intervals[-1][1] < interval[0]:
merged_intervals.append(interval)
# 否则,与上一个区间合并
else:
merged_intervals[-1][1] = max(merged_intervals[-1][1], interval[1])
return merged_intervals
排序与双指针
排序与双指针的解法与贪心算法类似,但具体实现方式有所不同:
- 对区间按照开始时间排序。
- 使用两个指针 left 和 right,left 指向当前考察的区间,right 指向与 left 重叠的区间。
- 当 left 和 right 指向的区间重叠时,更新 right 指向的区间为两个区间的合并区间。
- 当 left 指向的区间与 right 指向的区间不再重叠时,将 left 指向的区间添加到结果列表中,并将 left 和 right 指向下一个区间。
以下为 Python 实现:
def merge_intervals(intervals):
# 对区间按开始时间排序
intervals.sort(key=lambda x: x[0])
merged_intervals = []
left, right = 0, 1
while right < len(intervals):
if intervals[left][1] >= intervals[right][0]:
# 合并区间
intervals[left][1] = max(intervals[left][1], intervals[right][1])
right += 1
else:
# 添加非重叠区间
merged_intervals.append(intervals[left])
left = right
# 添加最后一个区间
merged_intervals.append(intervals[left])
return merged_intervals
总结
通过探索贪心算法和排序与双指针两种解法,我们可以看到,看似简单的算法题往往蕴藏着丰富的细节和多种可行的解法。每一种解法都有其优缺点,掌握不同的解法有助于我们解决更复杂的问题。
本文旨在深入挖掘“合并区间”问题的精髓,帮助读者理解算法题的内涵,培养解决问题的能力。无论是初学者还是算法高手,都能从中学到有价值的经验和见解。