我有一个输入数组 A
A[0], A[1], ... , A[N-1]
我希望有一个名为Max(T,A)的函数,它返回变量A上移动窗口大小为T时的最大值B。
B[i+T] = Max(A[i], A[i+T])
使用最大堆来跟踪当前移动窗口A [i]到A [i + T]上的最大值,该算法的最坏情况为O(N log(T))。我想知道是否有更好的算法?也许是O(N)算法。
使用双端队列数据结构可以实现O(N)。它保存了一对(值;索引)。
at every step:
if (!Deque.Empty) and (Deque.Head.Index <= CurrentIndex - T) then
Deque.ExtractHead;
//Head is too old, it is leaving the window
while (!Deque.Empty) and (Deque.Tail.Value > CurrentValue) do
Deque.ExtractTail;
//remove elements that have no chance to become minimum in the window
Deque.AddTail(CurrentValue, CurrentIndex);
CurrentMin = Deque.Head.Value
//Head value is minimum in the current window
准备工作完成后,你可以在O(1)
的时间复杂度内得到任何给定范围内的最大数。
我猜你甚至可以做一个运行版本,其中临时数组的长度为2*T
,但这将更加复杂。
van Herk,“一种用于矩形和八边形核的局部最小值和最大值滤波的快速算法”,Pattern Recognition Letters 13(7):517-521,1992年(doi)
Gil,Werman,“计算2-D最小值、中值和最大值滤波器”,IEEE Transactions on Pattern Analysis and Machine Intelligence 15(5):504-507,1993年(doi)
Gil,Kimmel,“高效膨胀、腐蚀、开启和关闭算法”,IEEE Transactions on Pattern Analysis and Machine Intelligence 24(12):1606-1617,2002年(doi)
A
是固定的而T
可变,则可以进行O(N * log(N))
的准备工作,然后对于每个T
,您可以在 O(N) 时间内获得B
。 - iloahz