Description
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example
Example 1:
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Example 2:
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
Submissions
这道题可以看做是上一题的进阶,因此我首先想到的是利用上一题解题思路,将newInterval列表添加到intervals中,再利用上一题代码进行合并即可。
实现代码如下:
class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
intervals = intervals + [newInterval]
if intervals == []:
return []
intervals.sort(key=lambda x:x[0])
res = [intervals[0]]
for i in intervals[1:]:
if res[-1][-1]>=i[0]:
res[-1][-1]= max(res[-1][-1],i[-1])
else:
res.append(i)
return res
但经过学习其他人的方法我发现了一个有趣的python内置模块-bisect,详细介绍可以参考
利用bisect_left 和 bisect_right 函数,可以实现解题。首先将intervals列表每个元素的首尾分成两个列表,然后将newInterval列表的首元素利用bisect_left 函数返回插入到end列表中的位置,将newInterval列表的尾元素利用bisect_right函数返回插入到start列表中的位置。最后如果两个位置相同,则直接插入newInterval,否则将l位置添加为start列表l位置元素与newInterval首元素中的最小值,将r位置添加为end列表r位置元素与newInterval尾元素中的最大值。最后返回插入结果即可。
实现代码如下:
from bisect import bisect_left, bisect_right
class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
start, end = [x for x,y in intervals] , [y for x,y in intervals]
l = bisect_left(end, newInterval[0])
r = bisect_right(start, newInterval[1])
if l == r:
intervals[l:r] = [newInterval]
else:
intervals[l:r] = [[min(start[l], newInterval[0]), max(end[r-1], newInterval[1])]]
return intervals