寻找最长的重叠区间对

时间:2018-04-12 02:20:47

标签: algorithm intervals overlap schedule

假设我有一个 n 积分区间[a,b]的列表,每个区间代表集合S = {a,a + 1,... b}。重叠定义为| S_1 \ cap S_2 |。示例:[3,6]和[5,9]在[5,6]上重叠,因此其长度为2.任务是使用Just-O(n ^ 2)找到两个间隔最长的区间递归和动态编程。

天真的方法显然是蛮力的,它不具备时间复杂性条件。尝试扫描线算法和/或最长公共子序列算法时,我也没有成功。

我找不到将其划分为子问题的方法。任何想法都将不胜感激。

还发现了这一点,在我看来根本不起作用:

Finding “maximum” overlapping interval pair in O(nlog(n))

2 个答案:

答案 0 :(得分:1)

这是一种花费N log(N)时间的方法。

将每个间隔[a,b] [c,d]细分为一对数组,如下所示:

pair<a,-1>
pair<b,a>
pair<c,-1>
pair<d,c>

sort these pairs in increasing order. Since interval starts are marked as -1, in case of ties interval they should come ahead of interval ends.

for i = 0 to end of the pair array
    if current pair represents interval start
        put it in a multiset
    else
        remove the interval start corresponding to this interval end from the multiset.
        if the multiset is not empty
            update the maxOverlap with (current_interval_end - max(minimum_value_in_multiset,start_value_of_current_interval)+1)

此方法应将maxOverlap更新为可能的最高值。

答案 1 :(得分:0)

保留有关两个最大重叠间隔max1max2的信息(开头为空)。

将输入列表[x1, y1] .. [xn, yn] = I1..In按值x排序,如果遇到相等则丢弃两个间隔中较短的一个。在推出时间间隔时,请更新max1max2

对于每个间隔,在线性时间中添加属性max,显示所有前面间隔的最大y值(在排序列表中):

rollmax = −∞
for j = 1..n do
  Ij.max = rollmax
  rollmax = max(rollmax, Ij.y)

在已排序,已过滤和扩展的输入列表上,执行以下查询。它使用一个不断扩展的区间子列表,其间隔小于当前搜索的区间Ii,作为递归函数SearchOverlap的输入。

for i = 2..n do
  SearchOverlap(Ii, 1, i − 1)
return {max1, max2}

函数SearchOverlap使用divide and conquer方法遍历排序列表Il, .. Ir。它将这样的列表想象成一个完整的二叉树,其间隔为Ic作为其本地根。测试Ic.max < I.max用于始终决定以与I最大重叠的间隔方向遍历二叉树(左/右)。请注意,I是查询间隔,与log(n)个其他间隔进行比较。另请注意,可能在此类遍历中传递最大可能的重叠间隔,因此检查函数SearchOverlap开头的最大重叠。

SearchOverlap(I , l, r)
c = ceil(Avg(l, r)) // Central element of queried list
if Overlap(max1, max2) < Overlap(I , Ic) then
  max1 = I
  max2 = Ic
if l ≥ r then
  return
if Ic.max < I.max then
  SearchOverlap(I , c + 1, r)
else
  SearchOverlap(I , l, c − 1)
return

最后返回最大的重叠间隔(如果不为空)。总复杂度为O(n log(n))