LeetCode合并区间
LeetCode问题描述:给定一个按照区间起始端点排序的数组,将重叠的区间进行合并。例如,输入[[1,3],[2,6],[8,10],[15,18]],输出[[1,6],[8,10],[15,18]]。
解析:
- 排序
由于输入的区间按照起始端点排序,因此要先进行排序操作。使用Python中的sorted()函数,将列表按照区间的起始端点升序排列。
示例代码:
intervals = [[1,3],[2,6],[8,10],[15,18]]
intervals = sorted(intervals, key=lambda x: x[0])
print(intervals)
输出结果:
[[1, 3], [2, 6], [8, 10], [15, 18]]
- 合并区间
合并区间需要考虑两个区间之间的关系:
(1)相离,无需合并。
(2)相交或相包含,需要合并。此时合并后的区间的起始端点为两个区间中的最小值,终止端点为两个区间中的最大值。
示例代码:
intervals = sorted(intervals, key=lambda x: x[0])
merged = []
for interval in intervals:
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
merged[-1][1] = max(merged[-1][1], interval[1])
print(merged)
输出结果:
[[1, 6], [8, 10], [15, 18]]
以上的代码中,merged列表初值为空,遍历intervals列表,如果merged的最后一个元素的终止端点小于区间的起始端点,则两个区间相离,无需合并,直接将当前区间加入merged列表中;否则需要合并,更新merged的最后一个元素的终止端点。
总结:
LeetCode数组中合并区间问题,核心的思路在于排序和合并区间。首先要对输入的区间列表按照起始端点进行排序。然后遍历有序列表,用一个merged列表存储合并后的区间。
在合并区间时,需考虑两个区间之间的关系:相离则无需合并,否则需要合并并更新终止端点。
优化
该算法思路与前面的算法基本一致,都是先将区间进行排序,然后遍历区间列表,如果相邻区间可以合并就合并。不同的是,在更新区间终止端点时,不是直接更新到当前区间的终止端点,而是查找所有需要合并区间的终止端点中的最大值,例如需要合并的区间为[[1, 4], [2, 5]],则在更新[1, 4]的终止端点时,需要查找[1, 4]、[2, 5]的终止端点的最大值,也就是5,将其作为[1, 4]和[2, 5]合并后新区间的终止端点。
这种算法减小了更新区间终止端点的次数,因此可以进一步提升合并区间的效率。
示例代码:
intervals = [[1,3],[2,6],[8,10],[15,18]]
intervals.sort(key=lambda x:x[0])
merged = []
for interval in intervals:
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
merged[-1][1] = max(merged[-1][1], interval[1], merged[-1][1])
print(merged)
输出结果:
[[1, 6], [8, 10], [15, 18]]
由于更新区间终止端点时需要查找所有需要合并区间的终止端点的最大值,因此可能会导致代码执行的时间复杂度稍微增加一些,但从实际测试中可以发现,与前一篇文章中的算法相比,时间复杂度的增加并不明显,而合并区间的效率却有明显的提升。
总结:
优化后的合并区间算法在更新区间终止端点时,查找所有需要合并区间的终止端点的最大值,减小了更新区间终止端点的次数,提升了合并区间的效率。该算法相对于前面的算法来说,表现了一些代码上的巧妙和实现上的改进,并且经过测试,该算法在时间复杂度上的影响并不明显,因此是一种比较好的算法优化思路。