计算移动最大值

发布于 2024-12-27 14:21:46 字数 758 浏览 1 评论 0原文

可能的重复:
查找大小为 n 的数组的所有大小为 l 的连续子数组中的最小值

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

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

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

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

非常感谢。

Possible Duplicate:
Find the min number in all contiguous subarrays of size l of a array of size n

I have a (large) array of numeric data (size N) and would like to compute an array of running maximums with a fixed window size w.

More directly, I can define a new array out[k-w+1] = max{data[k-w+1,...,k]} for k >= w-1 (this assumes 0-based arrays, as in C++).

Is there a better way to do this than N log(w)?

[I'm hoping there should be a linear one in N without dependence on w, like for moving average, but cannot find it. For N log(w) I think there is a way to manage with a sorted data structure which will do insert(), delete() and extract_max() altogether in log(w) or less on a structure of size w -- like a sorted binary tree, for example].

Thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ぺ禁宫浮华殁 2025-01-03 14:21:46

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

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

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

希望这有帮助!

There is indeed an algorithm that can do this in O(N) time with no dependence on the window size w. The idea is to use a clever data structure that supports the following operations:

  • Enqueue, which adds a new element to the structure,
  • Dequeue, which removes the oldest element from the structure, and
  • Find-max, which returns (but does not remove) the minimum element from the structure.

This is essentially a queue data structure that supports access (but not removal) of the maximum element. Amazingly, as seen in this earlier question, it is possible to implement this data structure such that each of these operations runs in amortized O(1) time. As a result, if you use this structure to enqueue w elements, then continuously dequeue and enqueue another element into the structure while calling find-max as needed, it will take only O(n + Q) time, where Q is the number of queries you make. If you only care about the minimum of each window once, this ends up being O(n), with no dependence on the window size.

Hope this helps!

中二柚 2025-01-03 14:21:46

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

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 - W 的列表 L3,使得 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]之间范围的最大值code>i 和下一个垂直线,而l1[i + W - 1] 是垂直线和 i + W - 1 之间的范围的最大值。

I'll demonstrate how to do it with the list:

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

with length N=23 and W = 4.

Make two new copies of your list:

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]

Loop from i=0 to N-1. If i is not divisible by W, then replace L1[i] with 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]

Loop from i=N-2 to0. If i+1 is not divisible by W, then replace L2[i] with 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]

Make a list L3 of length N + 1 - W, so that 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]

Then this list L3 is the moving maxima you seek, L2[i] is the maximum of the range between i and the next vertical line, while l1[i + W - 1] is the maximum of the range between the vertical line and i + W - 1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文