【问题标题】:Efficiently finding overlapping intervals from a list of intervals从间隔列表中有效地找到重叠间隔
【发布时间】:2013-08-22 06:49:40
【问题描述】:

这与寻找重叠区间有关。我知道如何在给出区间列表(区间树)的情况下这样做。我所拥有的是间隔列表。例如,

[2,6], [7,11]
[1,3], [5,10], [11,13]
[2,5], [6,8]

结果应该是

[2,3], [7,8]

我需要做的是找到所有列表中通用的间隔列表。

我认为这个问题类似于合并n 列表。问题是我不能应用列表的成对合并。应用此方法可能会导致重叠间隔丢失。所以我需要一次将所有列表合并在一起(而不是成对的)。

我可以使用区间树。将每个列表中的第一个间隔插入到间隔树中并找到重叠。从树中删除最弱的区间并从其中一个列表中插入下一个区间。我还没有完全弄清楚如何使用这种方法,但似乎它会变得太贵。

是否有任何有效的算法可以从区间列表中找到重叠区间?

其他信息: 列表中的间隔被排序。它们不重叠并形成一个序列。

【问题讨论】:

    标签: algorithm list data-structures intervals interval-tree


    【解决方案1】:

    创建一个单一的、排序的转换数组。每个过渡都有一个位置,以及一个基于您加入或离开多少间隔的累积数字。当您通过列表时,请跟踪您所处的区间数。当您处于与系列一样多的区间时,这就是您处于公共区间的时间。

    对于您的示例,转换将是:

    [2, 1], [6, -1], [7, 1], [11, -1],
    [1, 1], [3, -1], [5, 1], [10, -1], [11, 1], [13, -1]
    [2, 1], [5, -1], [6, 1], [8, -1]
    

    在按位置排序并合并后折叠为:

    [1, 1], [2, 2], [3, -1], [5, 0], [6, 0], [7, 1], [8, -1], [10, -1], [11, 0], [13, -1]
    

    它为您提供运行总计的转换:

    [1, 1], [2, 3], [3, 2], [7, 3], [8, 2], [10, 2], [13, 1]
    

    然后我们可以读出我们在 3 的间隔,一个从 23,另一个从 78。答案是什么。

    创建一个长列表并进行排序的想法无疑是额外的工作。相反,您可以创建这些列表并即时合并它们。节省是系列数日志而非事件数日志的一个因素。

    【讨论】:

    • 很抱歉,我在“它为您提供了运行总计的过渡”时失去了您。你能否详细说明一下。谢谢!
    • 第一个条目仍然是位置。第二个是到那个点的变化的总和。所以我们开始[1, 1],然后是[2, 1+2],然后是[2, 1+2-1],依此类推(因为更改遵循1, 2, -1, 0, 0, 1, -1, -1, 0, -1)。 0 个转换无关紧要,所以我放弃了它们。
    【解决方案2】:

    我对您想要做的事情的理解是将交集操作应用于间隔列表。您可以成对执行此操作,因为交集是关联的。

    我会做类似的事情

    Let S be the set of sets, R = s1, s1 in S
         for each set s2 in S / {s1}
                  for each element e1 in R
                      for each element e2 in s2 s.t. e1.sup < e2.inf
                        e1 <- intersection (e1, e2)
    

    而两个区间的交集运算是

     intersection (e1,e2):
        return new Interval(max(e1.inf, e2.inf), min (e1.sup, e2.sup));
    

    【讨论】:

    • 我猜这是一个蛮力解决方案!如果我能找到一个更有效的解决方案,我期待着。
    • 是的,它是 O(n)。如果你的集合是有序的,你可以在平均情况下做得更好(只要你遇到一个元素 e2 ,它的下限高于第二个元素的上限,就退出第二个循环。刚刚编辑了伪代码。
    【解决方案3】:

    您说每个单独的间隔列表都是排序的并且不重叠。所以,

    Keep track of where you are in each list, starting at the beginning of each.
    While none of the lists has run out:
        If the current intervals (one from each list) all overlap:
           Output the intersection of the current intervals
        Find which of the current intervals has the earliest end point
        Advance one position within that list.
    

    如果有 K 个区间列表和 N 个区间,如果以最直接的方式实现,这应该花费 O(NK) 时间,但您应该能够通过跟踪信息将其减少到 O(N log K) 时间关于堆或其他优先级队列中的当前间隔。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 2023-01-26
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多