【问题标题】:Best approach for finding the maximum array element in a given range在给定范围内查找最大数组元素的最佳方法
【发布时间】:2017-05-16 17:48:04
【问题描述】:

给定一个长度为nm的非负整数数组,查询由两个整数ab组成,期望在数组的索引[a,b]范围内找到最大值.请注意a 可以大于b,在这种情况下,所需的范围是从an,然后从1b。并且还给出了一个输入k,表示要考虑的范围的长度也是常数,即常数

例子:

INPUT:
6 3 5 ---> n,m,k
7 6 2 6 1 5 ---> integer array
1 5 ---> query 1
2 6 ---> query 2
4 2 ---> query 3
OUTPUT:
7
6
7

我参考了this 的文章,但无法了解如何处理a>b 的情况。有没有其他方法可以解决这个问题

【问题讨论】:

  • 更新了我的答案。请看一下。
  • 我也建议使用segment trees

标签: arrays algorithm data-structures time-complexity


【解决方案1】:

滑动窗口方式:

要使用提到的方法解决问题,即滑动窗口最大值,只需将输入数组附加到自身,如下所示:

7 6 2 6 1 5 7 6 2 6 1 5

a<=b 的情况正常工作。

对于a>bcase:考虑b = a + k。所以你的新范围是[a,a+k],你可以在不改变算法的情况下愉快地解决它。

要稍微优化上述方法,您可以先追加 k 元素。

如果您在每次查询到达时滑动,则每次查询需要O(n)k 非常接近或等于 n 是最坏的情况。


替代方法:大量查询和灵活范围的情况下使用以下方法。

您正在寻找范围查询,而这正是 Segment Trees 的热门用途。

This 教程找到给定范围内的最小值。我知道您已经要求最大,这只是您必须在代码中进行的微不足道的更改。

对于a>b 情况,查询两次[1,b],然后查询[a,n],并报告两者中的最大值。

预处理时间:O(n)

额外空间:O(n)

这种方法非常有效,因为它会回答O(logn)中的每个查询,这在您查询过多的情况下非常有用。


滑动窗口将输出所有范围内的最大元素,但您只需要给定范围内的最大元素。因此,不要使用滑动窗口方法,而是使用段树或Binary Indexed Trees。你会感受到真正在一个范围内查询而不是滑过的乐趣。 (如果范围是灵活的,则每次查询到达时滑动都不会扩展。)

【讨论】:

  • 由于范围的长度是恒定的(根据问题中的要求),您可以运行单个滑动窗口来获取 O(n) 中所有可能范围的最大值,因此它绝对可以很好地扩展。
  • @Dukeling:同意你的看法。让我们编辑语句以使其更有意义。谢谢!我希望 OP 能做出一些回应,因为社区正在付出更多努力,以使现有答案更有意义。
【解决方案2】:

我认为这可以通过分而治之的方法来完成,所以让我们看看上面的例子。

所以对于情况 a>b

find max for range (1,b), say max_b = max_in_range(1,b).
find max for range (a,n), say max_a = max_in_range(a,n).

现在您可以使用任何语言的内置 max 方法轻松地在两个数字之间获取最大值

ans = max(max_a, max_b)

但是像这样涉及范围的问题,您可以使用段树来解决它,这是开始的链接 - https://en.wikipedia.org/wiki/Segment_tree

希望这会有所帮助!

【讨论】:

  • 但文章中提到的技术仅计算大小范围k 的最大值。但是[a,n][1,b] 不是,因此不计算对吗?
  • aah 我实际上根本没有检查链接,让我用要使用的正确数据结构更新我的答案
猜你喜欢
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2010-11-27
  • 2018-04-14
相关资源
最近更新 更多