计算移动最大值

时间:2012-01-18 05:15:22

标签: performance algorithm data-structures max

  

可能重复:
  Find the min number in all contiguous subarrays of size l of a array of size n

我有一个(大)数值数据数组(大小为N),并希望计算一个具有固定窗口大小w的运行最大值数组。

更直接地说,我可以为out[k-w+1] = max{data[k-w+1,...,k]}定义一个新数组k >= w-1(假设基于0的数组,就像在C ++中一样)。

有没有比N log(w)更好的方法呢?

[我希望N中应该有一个线性的,而不依赖于w,就像移动平均线一样,却找不到它。对于N log(w),我认为有一种方法可以使用已排序的数据结构进行管理,该结构将insert()delete()extract_max()完全放在log(w)或更少的大小w的结构 - 例如排序的二叉树。

非常感谢。

2 个答案:

答案 0 :(得分:11)

确实有一种算法可以在O(N)时间内完成此操作而不依赖于窗口大小w。我们的想法是使用支持以下操作的聪明数据结构:

  • 排队,为结构添加新元素
  • 出列,从结构中删除最旧的元素,
  • Find-max ,返回(但不删除)结构中的最小元素。

这实际上是一个队列数据结构,支持访问(但不删除)最大元素。令人惊讶的是,如 this earlier question 中所示,可以实现此数据结构,使得这些操作中的每一个都以摊销的O(1)时间运行。因此,如果您使用此结构将w元素排入队列,则在根据需要调用find-max时连续将其他元素出列并排入结构中,它将只需要O(n + Q)时间,其中Q是数字你提出的问题。如果您只关心每个窗口的最小值,则最终为O(n),而不依赖于窗口大小。

希望这有帮助!

答案 1 :(得分:1)

我将演示如何使用列表:

L = [21, 17, 16, 7, 3, 9, 11, 18, 19, 5, 10, 23, 20, 15, 4, 14, 1, 2, 22, 13, 8, 12, 6]

长度N=23W = 4

制作列表的两个新副本:

L1 = [21, 17, 16, 7, 3, 9, 11, 18, 19, 5, 10, 23, 20, 15, 4, 14, 1, 2, 22, 13, 8, 12, 6]
L2 = [21, 17, 16, 7, 3, 9, 11, 18, 19, 5, 10, 23, 20, 15, 4, 14, 1, 2, 22, 13, 8, 12, 6]

i=0循环到N-1。如果i无法将W整除,则将L1[i]替换为max(L1[i],L1[i-1])

L1 = [21, 21, 21, 21, | 3, 9, 11, 18, | 19, 19, 19, 23 | 20, 20, 20, 20 | 1, 2, 22, 22 | 8, 12, 12]

i=N-2循环到0。如果i+1无法将W整除,则将L2[i]替换为max(L2[i], L2[i+1])

L2 = [21, 17, 16, 7 | 18, 18, 18, 18 | 23, 23, 23, 23 | 20, 15, 14, 14 | 22, 22, 22, 13 | 12, 12, 6]

制作长度为L3的{​​{1}}列表,以便N + 1 - WL3[i] = max(L2[i]

L1[i + W - 1])

然后此列表L3 = [21, 17, 16, 11 | 18, 19, 19, 19 | 23, 23, 23, 23 | 20, 15, 14, 22 | 22, 22, 22, 13] 是您搜索的移动最大值,L3L2[i]与下一个垂直线之间的最大范围,而i是最大值垂直线与l1[i + W - 1]之间的范围。