【发布时间】:2012-09-15 03:45:12
【问题描述】:
在一个未排序的数组中,(我们可以预处理这个数组)。我们如何在 O(1) 时间内回答以下查询?从索引 i 到 j 找到最大值
编辑: 预处理可能需要 O(n) 时间和 O(n) 顺序的额外内存,因此经常出现的查询在 O(1) 时间内得到回答......
【问题讨论】:
在一个未排序的数组中,(我们可以预处理这个数组)。我们如何在 O(1) 时间内回答以下查询?从索引 i 到 j 找到最大值
编辑: 预处理可能需要 O(n) 时间和 O(n) 顺序的额外内存,因此经常出现的查询在 O(1) 时间内得到回答......
【问题讨论】:
这个问题(称为范围最小查询问题)已解决(O(n) 预处理,O(1) 查询)。来自Wikipedia:
众所周知,O(n) 时间的预处理足以在 O(1) 时间内回答后续查询。结果方案的空间实际上非常小,即 O(n) 位(参见 Fischer & Heun (2007))。
RMQ 问题与您的问题完全相同(只需将“minimum”替换为“maximum”)。请参阅http://wcipeg.com/wiki/RMQ#Cartesian_trees 了解算法的草图及其正确性和内存/时间保证的证明。
另请参阅TopCoder tutorial,了解可用于解决此问题的不同选项的概述,这些选项基本上是按实现复杂性递增的顺序。
【讨论】:
没有内存限制或预处理限制?只需制作一个包含所有可能答案的 O(n2) 表(即,i 和 j 的每个可能值对应一个条目)。这张表可以在 O(n3) 时间内简单地制作,并且可以通过增量计算最大值很容易地降低到 O(n2)。
【讨论】:
这是不可能的。您将需要遍历数组以找到需要 O(n) 的最大值,或者您需要通过对数组进行排序(比 O(n) 更昂贵)或确定所有可能范围的最大值来预先计算will 比 O(n) 更昂贵,并且需要太多的内存。
【讨论】:
除非您的预处理可以大于 O(1),否则不可能。排序有什么问题?这只是 O(n*log(n))(如果允许基数排序,则为最大 O(n))。
【讨论】:
i 到j 中找到最大值,排序会使这些查询毫无意义。