【问题标题】:Decrease runTime to O(n)将运行时间减少到 O(n)
【发布时间】:2012-09-26 05:59:41
【问题描述】:

我收到了这个关于硬件的问题,但我不知道该怎么做:
数组 A[1...n] 包含从 0 到 n 的所有整数,除了一个。数组未排序。
在这个问题中,我们无法通过单个操作访问 A 中的整个整数。
A 的元素以二进制表示,我们可以用来访问它们的唯一操作是“获取 A[i] 的第 j 位”,这需要恒定的时间。

我必须在 O(n) 时间内找到丢失的整数。

正常情况下需要的时间是 O(NlgN) (在 N 数组上运行,并获取所有 N - lgn 位函数的位)。

如果不阅读所有位,我该怎么做?

【问题讨论】:

  • 还有其他属性吗?例如。数组中的数字是有序的吗?否则,每个位都至少看一次是不可能的。
  • 另外,请发布您现在的解决方案。
  • 提示:分而治之。显然,您首先需要检查所有数字中的一些,但是在您这样做之后是否有必要再次检查 all 数字的下一位?
  • @Jon 这对随机排序的数组有什么帮助?
  • @Jon 不,提示有助于理解。您提供的内容纯属通用陈词滥调。

标签: algorithm


【解决方案1】:

我们现在假设对于某些 k,n 是 2^k - 1。

让我们再看一个 k = 3 的例子。

000
001
010
011
100
101
110
111

您会注意到,当有一个完整集合时,如上图所示,每一列(每个数字的位置)都有相同数量的 1 和 0。当然,为了方便起见,我们将其显示为已排序,但实际上,我并不是说它是。

我们来看看下面的列表

000
001
010
011
100
110
111

我们查看所有元素的第一位 ( O(n) ) 并找出哪个计数小于另一个。

我们看到,对于第一位,有一个数字,其最高有效位中的 1 缺失。这意味着我们知道我们的数字在其最高位有一个。

基本上,我们分成两组,一组最高有效位为 1,另一组最高有效位为 0。较小的一组向我们展示了缺失数字的位。

我们在较小的分区上做同样的事情。

因为它是 O(n) + O(n/2) + O (n/4) ... 它基本上是 O(2n),即 O(n)。

编辑

一般情况请参考the following document, bottom of page 1

基本上,它涉及利用这样一个事实,即当 n 不是 2 的幂时,您可以考虑这样一个事实,即给定 n,您确切知道有多少应该属于 bit=1 分区和 bit=如果这是一个完整的集合,则为 0 分区。

【讨论】:

  • 我认为这行不通。您的算法有效,但仅当您拥有所有 3 位字时。只需取 n=6(即 7 个​​元素),并让缺失的为 0。然后你甚至在每一步都有相同数量的 0 和 1。因此,您必须查看每一位。这就是为什么我认为一般的分而治之的方法是行不通的,从一开始就没有假设(问题中没有给出)。
  • 是的。你是对的。但是如果你注意到了,我提到了我最初的假设,即元素的数量是 2 减 1 的幂。我将很快调整我的解决方案来解决这种情况。我正在为此查看我的笔记。
猜你喜欢
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 2020-06-13
  • 2016-12-23
  • 2015-07-20
  • 2015-06-02
  • 1970-01-01
  • 2017-08-13
相关资源
最近更新 更多