【问题标题】:Intersections of intervals区间的交点
【发布时间】:2021-11-17 00:15:09
【问题描述】:

我了解start[i](第一个列表)和end[i](第二个列表)正在创建一个新输出作为新列表,但是如何使用 for 循环或理解列表遍历两个列表?有人可以提供更高效的代码吗?

这是场景:

您将获得两个封闭区间列表,firstListsecondList,其中 firstList[i] = [starti, endi]secondList[j] = [startj, endj]。每个区间列表都是成对不相交的,并按排序顺序排列。

返回这两个区间列表的交集。

闭区间[a, b](与a <= b)表示实数集xa <= x <= b

两个闭区间的交集是一组实数,它们要么为空,要么表示为闭区间。比如[1, 3][2, 4]的交集是[2, 3]

示例 1:

  输入:

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

  输出:

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

示例 2:

  输入:

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

  输出:

[]

这是我所拥有的,但我想要更少的代码:

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

【问题讨论】:

  • 请正确格式化您的代码并包含一些测试数据 - 您没有提供 intervalsN 的示例,并且示例中提到了您未使用的 firstListsecondList。代码缩进会导致语法错误。

标签: python list-comprehension


【解决方案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

这假设间隔是不相交的,但无论排序如何都可以工作。这是非常低效的,因为一旦您找到了一个匹配的交叉点,您就不需要继续检查所有其他交叉点。

【讨论】:

    【解决方案2】:

    您可以将两个列表的值与标识范围的开始 (1) 和结束 (3) 的标志合并。对值进行排序,然后通过它们累积标志(+1 表示开始,-1 表示结束)以确定两个列表是否具有覆盖每个值的范围:

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

    请注意,我假设范围在给定列表中永远不会重叠

    【讨论】:

      【解决方案3】:

      结束了: 你觉得呢?

      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
      

      【讨论】:

      • 我觉得不错!很高兴使它成为 O(len(A) + len(B)) 而不是 O(len(A)*len(B))。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-19
      • 2018-10-05
      • 1970-01-01
      相关资源
      最近更新 更多