如何找到给定数组中某个固定给定长度的每个子数组的最大值

2024-03-20

给定一个包含 n 个元素的数组和一个整数 k。假设我们想要在数组上滑动一个长度为 k 的窗口,报告每个窗口中包含的最大值。例如,给定数组

15  10   9  16  20  14  13

给定一个长度为 4 的窗口,我们将输出

[15  10   9  16] 20  14  13   ---> Output 16
 15 [10   9  16  20] 14  13   ---> Output 20
 15  10 [ 9  16  20  14]  13  ---> Output 20
 15  10   9 [16  20  14  13]  ---> Output 20

所以结果是

16  20  20  20

我通过跟踪窗口每个点的最大元素来解决这个问题,但是当最大元素滑出窗口时遇到了问题。那时,我想不出一种快速的方法来找出最大的剩余元素是什么。

有谁知道解决这个问题的有效算法?


这个老问题 https://stackoverflow.com/questions/4802038/implement-a-queue-in-which-push-rear-pop-front-and-get-min-are-all-constan/4802327#4802327讨论如何在 O(1) 时间内构建支持插入、出列和查找最小值的队列数据结构。请注意,这是not标准优先级队列,而是一个在任何时候都可以在 O(1) 时间内找到它包含的最小元素的值的队列。您可以轻松修改此结构以支持 O(1) 中的 find-max 而不是 find-min,因为这与这个特定问题更相关。

使用这个结构,你可以在 O(n) 时间内解决这个问题,如下所示:

  1. 将数组的前 k 个元素放入特殊队列中。
  2. For each element in the rest of the array:
    1. 使用队列的 find-max 操作报告当前子范围的最大元素。
    2. 将一个元素从队列中出列,保留旧范围的最后 k-1 个元素。
    3. 将序列中的下一个元素加入队列,使队列现在保存序列的下一个 k 元素子范围。

这总共需要 O(n) 时间,因为您访问每个数组元素一次,每个元素最多入队和出队一次,并且调用 find-max 恰好 n-k 次。我认为这很酷,因为复杂性是独立于 k,这最初看起来并不一定是可能的。

希望这可以帮助!感谢您提出一个很酷的问题!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何找到给定数组中某个固定给定长度的每个子数组的最大值 的相关文章

随机推荐