【问题标题】:A[j] = 2∗A[i] in list with better than O(n^2) runtime列表中的 A[j] = 2∗A[i] 优于 O(n^2) 运行时间
【发布时间】:2013-11-15 20:24:14
【问题描述】:

我在下面列出了一个我遇到问题的问题。这个问题是一个远离 O(n^2) 解决方案的简单嵌套循环,但我需要它是 O(n)。任何想法应该如何解决?有可能形成两个方程吗?

给定一个整数数组 A,检查是否有两个索引 i 和 j 使得 A[j] = 2∗A[i]。例如,在数组 (25, 13, 16, 7, 8) 上,算法应该输出“true”(因为 16 = 2 * 8),而在数组 (25, 17, 44, 24) 上,算法应该输出“错误的”。描述这个问题的算法,其最坏情况下的运行时间优于 O(n^2),其中 n 是 A 的长度。

谢谢!

【问题讨论】:

    标签: java python arrays algorithm big-o


    【解决方案1】:

    templatetypedef 建议使用哈希表是一个很好的建议。我想进一步解释一下为什么

    这里的关键是要意识到您实际上是在寻找集合中的某个值。您有一组正在搜索 的数字(2 * 输入数组中的每个值),以及一组正在搜索 的数字(输入中的每个值大批)。您的蛮力天真案例只是直接在 search-in 数组中查找值。您想要做的是将您的“搜索输入”集预加载到查找速度比数组(如哈希表)更快的东西中,然后您可以从那里进行搜索。

    您还可以通过不搜索A[i] 来进一步修剪结果,其中A[i] 是奇数;因为你知道如果A[i] 是奇数,A[i] = 2 * A[j] 永远不会是真的。您还可以在初始化期间动态计算“搜索”数组中的最小值和最大值,并修剪该范围之外的所有A[i]

    那里的性能很难用大 O 形式表达,因为它取决于数据的性质,但您可以计算最佳和最坏情况以及摊销情况。

    但是,正确选择哈希表大小(如果您的值范围很小,您可以简单地选择一个大于您的值范围的容量,其中哈希函数就是值本身)实际上可能会使修剪成本更高在某些情况下,您必须对其进行分析才能找出答案。

    【讨论】:

      【解决方案2】:

      这是使用哈希表的好地方。创建一个哈希表并将数组中的每个数字输入到哈希表中。然后,再次遍历数组并检查每个 i 的哈希表中是否存在 2*A[i]。如果是这样,那么您知道该属性存在一对索引。如果没有,你就知道不存在这样的一对。

      按照预期,这需要 O(n) 时间,因为哈希表上的 n 次操作需要预期的摊销 O(1) 时间。

      希望这会有所帮助!

      【讨论】:

      • 为什么使用哈希表而不是集合?就因为你可以?
      • 这是一个考试练习题。这会是最快的方式(就写作而言)吗?一套也可以吗?我以前从未实现过哈希表。
      • @MattFenwick Python 集是根据哈希表实现的。
      • 不幸的是,根据 Python 时间复杂度图表,相交运算在这种情况下是 O(len(s) * len(t)) 或 O(n^2)。
      • @MattFenwick-当我写这个答案时,我注意到这个问题被标记为 [java] 和 [python]。我对 Python 没有太多经验,并认为我会根据适当的底层数据结构而不是像集合这样的具体类型来给出答案,以便我可以 (1) 保证跨越语言障碍的时间复杂度和 (2) 确保我不是不小心犯了 Python 错误。由于看起来 Python 中的集合是由哈希表支持的,因此在这种情况下使用集合似乎是合适的。
      猜你喜欢
      • 2013-08-19
      • 2022-01-13
      • 1970-01-01
      • 2018-09-16
      • 2012-04-16
      • 1970-01-01
      • 2020-12-11
      • 2018-03-04
      • 2021-11-01
      相关资源
      最近更新 更多