问题描述
例如:我有 intervals = [[-5,-3],[-4,-1],[1,3],[4,8],[5,10],[10,12],[15,20]]
(不需要这样排序)
我希望函数返回我 [[-5,20]]
。由于 [-5,-1] and [4,12]
有相互拦截的数字。即,我希望该函数返回所有“孤独”间隔以及它们的数字相互截取的间隔的并集的最小值和最大值。
def maxdisjointIntervals(list_):
# Lambda function to sort the list
# elements by second element of pairs
list_.sort(key = lambda x: x[1])
# First interval will always be
# included in set
print("[",list_[0][0],",list_[0][1],"]")
# End point of first interval
r1 = list_[0][1]
for i in range(1,len(list_)):
l1 = list_[i][0]
r2 = list_[i][1]
# Check if given interval overlap with
# prevIoUsly included interval,if not
# then include this interval and update
# the end point of last added interval
if l1 > r1:
print("[",l1,r2,"]")
r1 = r2
重复我之前说过的话:我希望它返回这个输出 [[-5,20]]
我希望我的解释不会过于冗长,因为我的母语不是英语。谢谢!
解决方法
所以我的理解是你想找到连接或重叠的区间,你可以通过使用迭代器来做到这一点。
def maxDisjointIntervals(intervals): # dont use list_ as your variable name
overlappedIntervals = []
if len(intervals) == 0:
return overlappedIntervals
# sort the intervals using the starting time
intervals = sorted(intervals,key=lambda interval: interval[0])
# init the start hour and end hour
startHour = intervals[0][0]
endHour = intervals[0][1]
for interval in intervals[1:]:
# if there is an overlap
if interval[0] <= endHour <= interval[1]:
endHour = interval[1]
# if there is not an overlap
else:
overlappedIntervals.append([startHour,endHour])
startHour = interval[0]
endHour = interval[1]
overlappedIntervals.append([startHour,endHour])
return overlappedIntervals
print(maxDisjointIntervals([[-5,-3],[-4,-1],[1,3],[4,8],[5,10],[10,12],[13,20]]))
输出:[[-5,20]]
您可以使用 functools 中的 reduce 将间隔合并在一起:
intervals = [[-5,[15,20]]
from functools import reduce
disjoints = [*reduce(lambda a,b: a+[b] if not a or b[0]>a[-1][1] else a[:-1]+[[a[-1][0],b[1]]],intervals,[])]
print(disjoints) # [[-5,20]]
或者在基本循环中做同样的事情:
disjoints = intervals[:1]
for s,e in intervals[1:]:
if s>disjoints[-1][-1]: disjoints.append([s,e])
else: disjoints[-1][-1] = e
print(disjoints) # [[-5,20]]
注意:这假定包含范围。如果结尾是独占的,请使用 >=
而不是 >
。