简体   繁体   中英

Intersections of intervals

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])
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.

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

ended up with this: what do you think?

def intervalIntersection(self, A: List[List[int]], B: List[List[int]]) -> List[List[int]]: ans = [] i = j = 0

    while i < len(A) and j < len(B):
        # Let's check if A[i] intersects B[j].
        # lo - the startpoint of the intersection
        # hi - the endpoint of the intersection
        lo = max(A[i][0], B[j][0])
        hi = min(A[i][1], B[j][1])
        if lo <= hi:
            ans.append([lo, hi])

        # Remove the interval with the smallest endpoint
        if A[i][1] < B[j][1]:
            i += 1
        else:
            j += 1

    return ans

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM