我想输入一个间隔列表并检查重叠间隔的并集间隔和非重叠间隔的间隔

问题描述

例如:我有 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]]

重复我之前说过的话:我希望它返回这个输出 [[-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]]

注意:这假定包含范围。如果结尾是独占的,请使用 >= 而不是 >