【问题标题】:find max between two indices of unsorted array in O(1) time在 O(1) 时间内找到未排序数组的两个索引之间的最大值
【发布时间】:2012-09-15 03:45:12
【问题描述】:

在一个未排序的数组中,(我们可以预处理这个数组)。我们如何在 O(1) 时间内回答以下查询?从索引 i 到 j 找到最大值

编辑: 预处理可能需要 O(n) 时间和 O(n) 顺序的额外内存,因此经常出现的查询在 O(1) 时间内得到回答......

【问题讨论】:

    标签: arrays search


    【解决方案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,了解可用于解决此问题的不同选项的概述,这些选项基本上是按实现复杂性递增的顺序。

    【讨论】:

      【解决方案2】:

      没有内存限制或预处理限制?只需制作一个包含所有可能答案的 O(n2) 表(即,ij 的每个可能值对应一个条目)。这张表可以在 O(n3) 时间内简单地制作,并且可以通过增量计算最大值很容易地降低到 O(n2)。

      【讨论】:

      • 最好在您提出问题时提及这些限制 :)
      【解决方案3】:

      这是不可能的。您将需要遍历数组以找到需要 O(n) 的最大值,或者您需要通过对数组进行排序(比 O(n) 更昂贵)或确定所有可能范围的最大值来预先计算will 比 O(n) 更昂贵,并且需要太多的内存。

      【讨论】:

      • 嗯,不,我认为这是看待问题的一种非常简单的方式。为什么不可能?不要提出错误的二分法——你需要一个真实的证据来证明这是不可能的。
      • 给出一个真实的证明需要一点 CS 理论。任何涉及算法设计和/或复杂性分析的 CS 课程都应该涵盖这个特定问题。
      • 这里实际上有一个理论上的解决方案:如果您的 CPU 数量与您正在查看的数组切片中的元素数量相同,您可以并行扫描所有元素以找到最大值。在实践中,您可能拥有比 CPU 更多的元素,并且通信开销可能远高于这种方法的任何理论上的好处,这使得这种方法不可行。
      • 考虑到新的约束条件,这个特殊的问题变得不那么容易了。 O(n) 预处理解决方案是在 2007 中发现的——鉴于大多数“简单”的 CS 复杂性理论问题在 70 年代和 80 年代得到解决,这表明该问题并不容易。我怀疑该证明是否包含在介绍 CS 理论课程中;)
      【解决方案4】:

      除非您的预处理可以大于 O(1),否则不可能。排序有什么问题?这只是 O(n*log(n))(如果允许基数排序,则为最大 O(n))。

      【讨论】:

      • 排序完全破坏了问题的意义——我们试图从索引ij 中找到最大值,排序会使这些查询毫无意义。
      • 是的,但是如果没有一些非常量时间的预处理,这是不可能的。排序和其他操作一样好。
      • 你将如何使用排序数组回答查询?
      • 自编辑后:创建一个大小为 n 的数组,其中包含从 0 到 n-1 递增的数字。在 n*log(n) 时间内使用您的第一个数组的比较函数对其进行排序。将新数组解释为索引。在 O(1) 中找到答案。
      • @nneonneo 说排序会破坏问题的意义是正确的
      猜你喜欢
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      相关资源
      最近更新 更多