从间隔列表中有效地找到重叠间隔

时间:2013-08-22 06:49:40

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

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

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

结果应为

  

[2,3],[7,8]

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

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

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

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

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

3 个答案:

答案 0 :(得分:4)

创建单个排序的转换数组。每个转换都有一个位置,累积数字取决于您加入或离开的间隔数。当您通过列表时,记录您所处的间隔数。当您处于与序列一样多的时间间隔时,就在您处于共同间隔时。

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

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

然后我们可以从2开始到3,从7开始,然后转到{{1 }}。答案就是这样。

创建一个长列表和排序的想法无疑是额外的工作。您可以改为创建这些列表并动态合并它们。节省量是系列数量的对数而不是事件数量的对数。

答案 1 :(得分: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));

答案 2 :(得分:2)

您说每个间隔列表都已排序且不重叠。所以,

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)时间关于堆或其他优先级队列中的当前间隔。