【问题标题】:Pseudo Range Minimum Query伪范围最小查询
【发布时间】:2013-10-23 00:02:42
【问题描述】:

我的作业有问题,需要我解决类似于 range-minimum-query 的问题。问题大致描述如下:

我应该编写一个 java 程序,它读取大量整数(大约 100,000)并将它们存储到一些数据结构中。然后,我的程序必须回答给定范围 [i,j] 中的最小数字的查询。我已经成功地设计了一种算法来解决这个问题。但是,它还不够快。

我的算法的伪代码如下:

// Read all the integers into an ArrayList

// For each query,
// Read in range values [i,j] (note that i and j is "actual index" + 1 in this case)
// Push element at index i-1 into a Stack
// Loop from index i to j-1 in the ArrayList (tracking the current index with variable k)
[Begin loop]       
// If element at k is lesser than the one at the top of the stack, push the element at k into the Stack.
[End of loop]

有人可以告诉我我可以做什么,以便我的算法足够快来解决这个问题吗?

作业文件可以在这个链接找到:http://bit.ly/1bTfFKa

我被这个问题困扰了好几天。任何帮助将非常感激。 谢谢。

【问题讨论】:

  • 您的问题听起来像完全的范围最小查询,有足够的材料可供使用。例如,请参阅this
  • 嗨。谢谢你的文章。我发现它很有帮助。是否可以使用基于堆栈的解决方案来解决此问题?我想知道这一点,因为任务简介实际上指出不需要 rmq 并且堆栈足以解决问题。
  • 如果你被告知使用堆栈,我猜你错过了问题描述的一些细节或描述不正确,因为如前所述,它是 RMQ,我不相信那里是一种有效的基于堆栈的解决方案(我们知道)。

标签: java algorithm stack rmq


【解决方案1】:

您的问题是静态范围最小查询 (RMQ)。假设你有 N 个数字。您可以使用的最简单的算法是创建一个大小为 N 的数组并存储数字的算法,另一个是大小为 sqrtN 的算法,并将保存数组中每个大小为 sqrtN 的间隔的 RMQ。这应该可行,因为 N 不是很大,但如果您有很多查询,您可能需要使用不同的算法。
话虽如此,您可以使用的最快算法是用数字制作一个稀疏表,这将允许您回答 O(1) 中的查询。构造稀疏表是 O(NlogN),给定 N = 10^5 应该没问题。
最后,最终的 RMQ 算法是使用 Segment Tree,它也支持更新(单元素和范围),构建 Segment Tree 的时间为 O(N),每次查询和更新的时间为 O(logN)。 所有这些算法都很好地暴露了here。 有关分段树的更多信息,请参阅我自己编写的这些教程。 link
祝你好运!

【讨论】:

  • 感谢您提供有用的链接。他们肯定看起来很有趣。当我有更多空闲时间时,将尝试实施分段树/稀疏表解决方案。无论如何,我设法通过将大小为 N 的输入数据预处理成大小的段(立方根 N)来解决这个问题。这是 Dukeling 提供的链接中所述的 RMQ 方法之一。
  • 干得好,最好的解决方案并不总是最快或最复杂的解决方案,而是以最简单的方式解决特定问题的解决方案。顺便说一句,我建议学习 Segment Trees,因为它是一种非常通用的数据结构,适用于许多范围查询(如范围求和查询,甚至 GCD 查询)
猜你喜欢
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 2013-01-24
  • 2021-08-17
  • 2017-01-16
相关资源
最近更新 更多