Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 计算移动最大值_Performance_Algorithm_Data Structures_Max - Fatal编程技术网

Performance 计算移动最大值

Performance 计算移动最大值,performance,algorithm,data-structures,max,Performance,Algorithm,Data Structures,Max,可能重复: 我有一个(大的)数值数据数组(大小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),我认为有一种方法可以通过排序数据结构来管理,insert(),delete()和extract_max()一起在log(w

可能重复:

我有一个(大的)数值数据数组(大小
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)
,我认为有一种方法可以通过排序数据结构来管理,
insert()
delete()
extract_max()
一起在
log(w)中完成
或更小的大小的结构上的
w
——例如,像排序的二叉树]


非常感谢。

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

  • 排队,为结构添加新元素
  • 退出队列,从结构中删除最旧的元素,以及
  • 查找max,它返回(但不删除)结构中的最小元素
这本质上是一个队列数据结构,支持访问(但不删除)最大元素。令人惊讶的是,正如在中所看到的,可以实现这种数据结构,从而使这些操作中的每一个都在摊销O(1)时间内运行。因此,如果使用此结构将w个元素排队,然后在调用find max(根据需要)的同时将另一个元素连续出列并排队到该结构中,则只需要O(n+Q)时间,其中Q是您进行的查询数。如果只关心每个窗口的最小值一次,那么结果是O(n),与窗口大小无关


希望这有帮助

我将演示如何使用列表:

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])

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

列出长度为N+1-W的
L3
,以便
L3[i]=max(L2[i]
L1[i+W-1])


然后该列表
L3
是您所寻求的移动最大值,
L2[i]
i
和下一条垂直线之间的最大范围,而
l1[i+W-1]
是垂直线和
i+W-1

之间的最大范围,很好,我不得不对这个答案和您引用的答案进行投票!我必须在这里指出,双堆栈队列实现不一定是最好的。我尝试过它,用于实时应用程序,结果是灾难性的。。。根据应用程序的不同,还可以尝试deque(双端队列)结构,该结构也将给出O(N)的总体结果,但不一定要为出列操作摊销O(1)。我在一个数组上实现了一个循环deque,效果很好。请同时查看此问题:。
L1 = [21, 21, 21, 21, | 3, 9, 11, 18, | 19, 19, 19, 23 | 20, 20, 20, 20 | 1, 2, 22, 22 | 8, 12, 12]
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 = [21, 17, 16, 11 | 18, 19, 19, 19 | 23, 23, 23, 23 | 20, 15, 14, 22 | 22, 22, 22, 13]