搜索缺失的数字 - 简单的例子

时间:2015-06-13 11:46:51

标签: c algorithm

在C中搜索算法和复杂性的一个小任务。我只是想确保我正确。

我有从1到n + 1的n个自然数,从小到大排序,我需要找到丢失的数字。 例如:1 2 3 5 6 7 8 9 10 11 - ans:4

最快和最简单的答案是做一个循环,并用它后面的数字检查每个数字。在最坏的情况下,复杂性是O(n)。

我想也许我错过了一些东西,我可以使用二进制搜索找到它。在这个简单的例子中,有人能想到更高效的算法吗? 喜欢O(log(n))还是什么?

2 个答案:

答案 0 :(得分:1)

显然有两个答案:

如果您的问题纯粹是理论上的问题,特别是对于大型n,您可以执行类似二进制搜索的操作,并检查最后两个边界之间的中间位置是否实际为(upper-lower)/2

然而,如果这是一个实际问题,对于现代系统执行用C编写并由n << 10000的现代高度优化编译器编译的程序,我假设线性搜索方法更快,更快,因为它可以很容易地进行矢量化。事实上,现代CPU有指令要采取例如每个

  1. 一次4个整数,减去其他四个整数,
  2. 将结果与[4 4 4 4]
  3. 进行比较
  4. 将计数器增加4,
  5. 加载接下来的4个整数,
  6. 等等,它非常巧妙地适用于CPU和内存控制器预取线性内存的事实,因此,以对数下降步长跳转可能会产生巨大的性能影响。

    所以:对于大型n,线性搜索不切实际,请选择二元搜索方法;对于那些有问题的n,请进行线性搜索。如果您不仅具有SIMD功能而且还具有多个内核,那么您将需要分解问题。如果您的问题实际上不是正好1 缺失的数字,您可能希望使用完全不同的方法......整个O(n)业务通常更像是一个纯粹用于理论构造的基准,除非差异非常大,否则很少是在实际实现中选择特定算法的唯一理由。

答案 1 :(得分:0)

对于基于比较的算法,在最坏的情况下,您无法胜过Lg(N)比较。这只是因为答案是1N之间的数字,并且需要Lg(N)位信息来表示这样的数字。 (并且比较会给你一点。)

除非答案的分布非常偏离,否则你的平均成绩不会比Lg(N)好得多。

现在我不知道基于非比较的方法如何利用序列的有序性,并且比O(N)做得更好。