在包含最多40亿个整数的未排序数组中找到缺失的32位整数

时间:2009-10-29 09:18:40

标签: algorithm binary-search programming-pearls

这是Programming pearls中描述的problem。我无法理解作者所描述的二进制搜索方法。任何人都可以帮忙详细说明吗?感谢。

编辑: 我可以理解二进制搜索。我只是无法理解如何在这种特殊情况下应用二进制搜索。如何确定缺失的数字是否在某个范围内,以便我们可以选择另一个。英语不是我的母语,这是我无法理解作者的一个原因。所以,请使用普通英语:)

编辑:谢谢大家的好评和评论!我从解决这个问题中学到的最重要的一课是二进制搜索不仅适用于排序数组

6 个答案:

答案 0 :(得分:9)

有关this web site的更多信息。引自那里:

“根据表示每个整数的20位来查看这个二进制搜索是有帮助的。在算法的第一遍中,我们读取(最多)一百万个输入整数,并将那些前导零位写入这两个磁带中有一个包含最多500,000个整数,因此我们接下来使用该磁带作为当前输入并重复探测过程,但这次是在第二个位上。原始输入磁带包含N个元素,第一次传递将读取N个整数,第二次传递最多为N / 2,第三次传递最多为N / 4,依此类推,因此总运行时间与N成正比。缺少的整数可以通过在磁带上排序然后扫描来找到,但这需要与N log N成比例的时间。“

正如您所看到的,这是二元搜索算法的一种变体:将问题分成两部分并解决其中一个较小部分的问题。

答案 1 :(得分:2)

我相信作者得到的是你选择当前整数范围的中点,并准备两个输出文件。当您阅读输入时,中点以上的所有内容都会进入一个文件,而中点以下的所有内容都会进入另一个文件。

一旦完成,你选择较小的文件,然后重复操作,使用[下限,中点]或(中点,上限)作为新范围,直到文件和范围足够小到切换到位图模式(或者您的一个输出文件为空)。

达明

答案 2 :(得分:2)

一般的想法是:选择一系列整数,并选择属于该范围的所有整数。如果整数的数量小于范围的大小,则表示该范围包含一个或多个缺失的数字。

这也适用于你如何知道首先缺少一些数字的原始问题。

答案 3 :(得分:2)

如果您考虑的数字范围为1到N;其中一半大于N / 2,其中一半小于N / 2

大于N / 2的那些将MSB设置为1; 对于较小的MSB,MSB = 0.

基于MSB对整个集合进行分区,它将为您提供两组:小于N / 2的数字集合和大于N / 2的数字集合

更小的分区具有缺少的元素。

在下一步中,使用下一个MSB。

  1. 如果较小的集合小于N / 2,则其中一半小于N / 4(第二个MSB = 0)而另一半小于N / 4(第二个MSB = 1)

  2. 如果较小的集合大于N / 2,则其中一半小于N / 2 + N / 4(第二个MSB = 0),另一半大于N / 2 + N / 4(第二个MSB = 1)

  3. 每一轮都会将搜索空间减半,就是这样。

     Sum ( N / 2^i ) for 0 <= i < log N gives you O(N)
    

答案 4 :(得分:2)

这与this question基本相同。相同的方法适用于充足的内存情况,以获得O(N)复杂性。基本上只是递归尝试将每个整数放到正确的位置,看看什么没有正确的值。

答案 5 :(得分:1)

嗯,它是关于一个包含除了一个以外的所有40亿个整数的文件!这就是本案中的问题。

  1. 沿着整数列表移动时,计算总和。
  2. 最后,使用公式N *(N + 1)/ 2
  3. 计算总和,就好像存在所有整数一样
  4. 从(2)处计算的总和中提取(1)处的和。那是缺少的整数。
  5. 实施例: 假设我们有以下顺序:9 3 2 8 4 10 6 1 7(1到10,缺少5个)。当我们按顺序添加整数时,得到9 + 3 + 2 + 8 + 4 + 10 + 6 + 1 + 7 = 50.从1到10的所有整数之和为10 *(10 + 1)/ 2 = 55因此,缺失的整数是55 - 50 = 5. QED