Home > Mobile >  Intersections of intervals
Intersections of intervals

Time:11-17

I understand that start[i] (first list) & end[i](second list) are creating a new output as new list but how to iterate through the twolist with a for loop or comprehension list? Can someone provide a more efficient code?

Here is the scenario:

You are given two lists of closed intervals, firstList and secondList, where firstList[i] = [starti, endi] and secondList[j] = [startj, endj]. Each list of intervals is pairwise disjoint and in sorted order.

Return the intersection of these two interval lists.

A closed interval [a, b] (with a <= b) denotes the set of real numbers x with a <= x <= b.

The intersection of two closed intervals is a set of real numbers that are either empty or represented as a closed interval. For example, the intersection of [1, 3] and [2, 4] is [2, 3].

Example 1:

  Input:

firstList = [[0,2],[5,10],[13,23],[24,25]]
secondList = [[1,5],[8,12],[15,24],[25,26]]

  Output:

[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]

Example 2:

  Input:

firstList = [[1,3],[5,9]]
secondList = []

  Output:

[]

This is what I have but I want less lines of code:

l = intervals[0][0]
r = intervals[0][1]

for i in range(1,N):

    # If no intersection exists
    if (intervals[i][0] > r or intervals[i][1] < l):
        print(-1)

    # Else update the intersection
    else:
        l = max(l, intervals[i][0])
        r = min(r, intervals[i][1])

CodePudding user response:

intervals1 = [[0,2],[5,10],[13,23],[24,25]]
intervals2 = [[1,5],[8,12],[15,24],[25,26]]

def get_intersection(interval1, interval2):
    new_min = max(interval1[0], interval2[0])
    new_max = min(interval1[1], interval2[1])
    return [new_min, new_max] if new_min <= new_max else None

interval_intersection = [x for x in (get_intersection(y, z) for y in intervals1 for z in intervals2) if x is not None]
print(interval_intersection)

Try it at www.mycompiler.io

This assumes that the intervals are disjoint but would work regardless of ordering. It is very slightly inefficient in that once you have found one matching intersection you don't need to keep checking all the others.

CodePudding user response:

You could merge the values of the two list with a flag identifying starts (1) and ends (3) of ranges. Sort the values and then go through them accumulating the flags ( 1 for starts, -1 for ends) to determine if both lists have a range covering each value:

firstList = [[0,2],[5,10],[13,23],[24,25]]
secondList = [[1,5],[8,12],[15,24],[25,26]]

breaks = sorted((n,f) for a,b in firstList secondList for n,f in [(a,1),(b,3)])
merged,s = [[]],0
for n,flag in breaks:
    s  = 2-flag
    if s>=2 or s==1 and flag>1: merged[-1].append(n)
    if s<2 and merged[-1]:  merged.append([]) 
merged = merged[:-1]

print(merged)
[[1, 2], [5, 5], [8, 10], [15, 23], [24, 24], [25, 25]]

Note that I'm assuming that the ranges never overlap within a given list

  • Related