【问题标题】:Computing a moving maximum [duplicate]计算移动最大值
【发布时间】:2012-01-18 05:15:22
【问题描述】:

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

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

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

还有比N log(w)更好的方法吗?

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

非常感谢。

【问题讨论】:

    标签: performance algorithm data-structures max


    【解决方案1】:

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

    • Enqueue,向结构中添加新元素,
    • Dequeue,从结构中移除最旧的元素,并且
    • Find-max,从结构中返回(但不删除)最小元素。

    这本质上是一个队列数据结构,支持访问(但不删除)最大元素。令人惊讶的是,正如 this earlier question 中所见,可以实现这种数据结构,使得这些操作中的每一个都在平均 O(1) 时间内运行。因此,如果你使用这个结构将 w 个元素​​入队,然后在根据需要调用 find-max 的同时不断地出队并入队另一个元素,只需要 O(n + Q) 时间,其中 Q 是您提出的查询。如果您只关心每个窗口的最小值一次,则最终结果为 O(n),与窗口大小无关。

    希望这会有所帮助!

    【讨论】:

    • 太好了,我不得不对这个答案和你引用的答案都投赞成票!
    • 我必须在这里评论一下,两栈队列实现不一定是最好的。我已经尝试过,对于一个实时应用程序,结果是灾难性的......根据应用程序,人们也可以尝试双端队列(双端队列)结构,这也会给出 O(N) 的整体结果,但不一定为出队操作摊销 O(1)。我做了一个在数组上实现的循环双端队列,效果很好。也看看这个问题:stackoverflow.com/questions/12329073/….
    【解决方案2】:

    我将演示如何使用列表进行操作:

    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]
    

    制作一个长度为N + 1 - WL3列表,这样L3[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]
    

    那么这个列表L3是你寻找的移动最大值,L2[i]i和下一条垂直线之间范围的最大值,而l1[i + W - 1]是垂直线和下一条垂直线之间范围的最大值i + W - 1.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      • 2019-10-18
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      • 2013-05-13
      • 2016-11-04
      相关资源
      最近更新 更多