Merging Overlapping Intervals

前端 未结 4 2025
花落未央
花落未央 2020-12-10 14:31

Currently, I have intervals of:

temp_tuple = [[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18],          


        
相关标签:
4条回答
  • 2020-12-10 14:52

    The salient feature of the solution below is to run a list called final parallel to the input list. Before entering the for loop, the final list inserts the first array item in it. Then starts the comparison. That's it!

    def merger(a):
    
        final=[]
    
        final.append(a[0])
    
        for i in range(1,len(a)):
    
            if a[i][0]<=final[-1][1]:
    
               if a[i][1]>final[-1][1]:
    
                   low_limit=final[-1][0]
                   hi_limit=a[i][1]
                   final.pop()
                   final.append([low_limit,hi_limit])
    
               if a[i][1]<=final[-1][1]:
    
                    low_limit=final[-1][0]
                    hi_limit=final[-1][1]
                    final.pop()
                    final.append([low_limit,hi_limit])
    
              if final[-1][0]<a[i][1]<final[-1][1]:
    
               low_limit=a[i][0]
               hi_limit=final[-1][1]
               final.pop()
               final.append([low_limit,hi_limit])
    
    
    
            else:
                final.append(a[i])
    
        return final
    
    if __name__=="__main__":
    
        array=[[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18], [14, 17], [22, 27], [25, 30], [26, 29]]
        print(merger(array))
    

    Output:

    [[-25, -14], [-10, -3], [2, 6], [12, 18], [22, 30]]
    
    0 讨论(0)
  • 2020-12-10 14:52
    #Given an array of intervals in sorted order and a new interval, return a sorted array after merging the interval
    
    def mergeinter(intervals,newinter):
        n = len(intervals)
        start = newinter[0]# we mark the start and end of the new interval to be merged
        end = newinter[1]
        right,left = 0,0
        while right < n:# we track where this new interval belongs, i.e. how many interval are to the left of it and how many are to the right
            if start <= intervals[right][1]:# we find the first interval before which it fits
                if end < intervals[right][0]:# this checks if the interval is disjoint and lies between two given intervals
                    break# in this case we have nothing to do and go to line 29 directly
                start = min(start,intervals[right][0])# if it intersects with the given intervals then we just update and merge the ends
                end = max(end,intervals[right][1])
            else:# counting how many to the left continuing from line 20
                left += 1 
            right += 1# moving right to find the fit continuation of line 20 and even if we merge in line 25, we go to the next interval before
        return intervals[:left] + [(start,end)] + intervals[right:] # we return starting from the next interval
    
    #Given a collection of intervals, merge all overlapping intervals and return sorted list of disjoint intervals.
    
    def merge(I):
        I.sort(key:lambda i:i[0])# sorting according to the start of all intervals
        res = []# we start from the last of the given arr of lists and check the ends of the intervals and merge from the end
        for i in I:
            if not res or res[-1][0] < i[1]:# if res is empty then we put an elem in it from I
                res.append(i)# if there is no overlap, just add it
            else:
                res[-1][1] = max(i[1], res[-1][1])# here we merge from the end so that res remains sorted
        return res
    
    0 讨论(0)
  • 2020-12-10 14:54

    It makes it a bit easier to process (as in think about) if you instead setup a new list. You additionally also get to keep your original data.

    temp_tuple.sort(key=lambda interval: interval[0])
    merged = [temp_tuple[0]]
    for current in temp_tuple:
        previous = merged[-1]
        if current[0] <= previous[1]:
            previous[1] = max(previous[1], current[1])
        else:
            merged.append(current)
    

    If you now print(merged) it would output:

    [[-25, -14], [-10, -3], [2, 6], [12, 18], [22, 30]]
    
    0 讨论(0)
  • 2020-12-10 15:02

    This is a numpy solution I came up with:

    import numpy as np
    
    def merge_intervals(intervals):
        starts = intervals[:,0]
        ends = np.maximum.accumulate(intervals[:,1])
        valid = np.zeros(len(intervals) + 1, dtype=np.bool)
        valid[0] = True
        valid[-1] = True
        valid[1:-1] = starts[1:] >= ends[:-1]
        return np.vstack((starts[:][valid[:-1]], ends[:][valid[1:]])).T
    
    #example
    a=[]
    a.append([1,3])
    a.append([4,10])
    a.append([5,12])
    a.append([6,8])
    a.append([20,33])
    a.append([30,35])
    
    b = np.array(a)
    
    print("intervals")
    print(b)
    print()
    print("merged intervals")
    print(merge_intervals(b))
    

    Output:

    intervals
    [[ 1  3]
     [ 4 10]
     [ 5 12]
     [ 6  8]
     [20 33]
     [30 35]]
    
    merged intervals
    [[ 1  3]
     [ 4 12]
     [20 35]]
    

    Please note that the input array must be sorted by start positions.

    0 讨论(0)
提交回复
热议问题