Python 练习题(一)【python-leetcode56-区间合并】合并区间
问题描述:给出一个区间的集合,请合并所有重叠的区间。
示例 :
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
分析一
提示
区间右边的值大于左边的值
intervals[i][0] <= intervals[i][1]
解题思路
解题的第一步首先要将区间按区间第一个值的大小排序。使用Python的内置函数sort()进行排序,利用参数key对区间的第一个值升序排序。
q = sorted(intervals, key=lambda x:x[0])
如何判断区间有重叠呢?
intervals[i][1] >= intervals[i+1][0]
我为何不按照上式往下写呢?因为直接对intervals合并区间后,i 的值会超出索引,一个重叠区间好办,但是重叠区间的个数不确定时,在循环遍历的过程中,循环变量 i 会超过列表的索引。
代码:
def merge(intervals): if intervals ==[]: [(1, 2), (1, 3), (1, 5), (2, 4), (3, 6), (9, 11), (9, 16), (12, 17)] return [] intervals = sorted(intervals, key=lambda x:x[0]) #对输入的intervals进行排序 invalNow = intervals[0] # (min.max) result = [] for i in range (1,len(intervals)): if(invalNow[1]>=intervals[i][0]): # 只要上一个区间右边(较大)的值大于或等于下一个区间左边(较小)的值 invalNow[1] = max(invalNow[1],intervals[i][1]) else: result.append(invalNow) invalNow=intervals[i] result.append(invalNow) return result Example: >>> data = [[1,3],[2,6],[8,10],[15,18]] >>> merge(data) [[1, 6], [8, 10], [15, 18]]
分析二
核心:其实是贪心法的体现.先对二维数组按一维数组的第0位进行排序,假设结果是res=[]。当res为空时先将[1,3]加入到res中,再遍历到[2,6],此时有两种情况,如果当前数组的第0位大于res中最后一个数组的第1位,说明当前数组和res末尾的数组不会重叠,此时之间将当前数组加到res末尾。如果当前数组第0位小于或等于res末尾数组第1位,再判断当前数组第1位和res末尾数组第一位誰大,将其更新res末尾数组的第一位。依次类推。
代码:
def merge(intervals): res = [] intervals.sort() for i in intervals: if not res or res[-1][1]<i[0]: res.append(i) else: res[-1][1] = max(res[-1][1],i[1]) return res
结果:
分析三
题目解析
- 对数组排序
- while遍历数组,从第2个元素开始,当该元素首数小于前一个元素的尾数时,合并。合并的结果为[前一个元素的首数,max(前一个元素的尾数,当前元素的尾数)],并pop当前元素。否则 继续遍历。
def merge(self, intervals: List[List[int]]) -> List[List[int]]: intervals, index = sorted(intervals), 1 while index < len(intervals): if intervals[index - 1][1] >= intervals[index][0]: intervals[index - 1][1] = max(intervals[index - 1][1], intervals[index][1]) intervals.pop(index) else: index += 1 return intervals