可能重复:
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
的结构 - 例如排序的二叉树。
非常感谢。
答案 0 :(得分:11)
确实有一种算法可以在O(N)时间内完成此操作而不依赖于窗口大小w。我们的想法是使用支持以下操作的聪明数据结构:
这实际上是一个队列数据结构,支持访问(但不删除)最大元素。令人惊讶的是,如 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=23
和W = 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 - W
,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]
之间的范围。