删除偶数/奇数以查找以二进制表示的数字数组数组中的缺失数字

时间:2015-05-14 19:08:40

标签: arrays algorithm bits

这与第5版Cracking the coding面试中的问题5.7(在Bit Manipulation下)有关(如果问题不适合SO,请让我知道正确的网站,我会移动它):< / p>

  

数组A [1..n]包含从0到n的所有整数,除了一个   丢失的号码。在这个问题上,我们无法访问整个   A中的整数,只有一个操作。 A的元素是   以二进制表示,是我们可以用来访问的唯一操作   它们是“获取A [i]的第j位”,这需要恒定的时间。写   用于查找缺少的整数的代码。你能在O(n)时间内完成吗?

应用的算法是:

  1. 检查列表中所有数字的LSB。
  2. 计算LSB中1和0的出现次数。 如果count(0)&lt; = count(1),则缺失数字的LSB为0.否则为1.
  3. 删除所有数字,其中LSB与步骤2中找到的结果不匹配。
  4. 重复1到4,逐步检查每次迭代中的下一个LSB​​。
  5. 有人可以解释第3步背后的逻辑吗?它基本上从当前列表中删除所有奇数/偶数(取决于找到的缺失数字的位),并在下一次迭代中使用修改后的列表。我们为什么要这样做?

2 个答案:

答案 0 :(得分:1)

步骤3旨在(大大)改进算法的运行时间。如果包括步骤3,则整个算法是使用LSB作为分支决策器的二进制搜索算法。如果省略步骤3,那么它仍然是二进制搜索,但是在每次传递时不会以对数方式更快的方式实现(这将超过O(n)界限)。

顺便说一句,正如所写的那样,似乎缺少一点移位,或者LSB这个术语以相当宽松的方式使用。

答案 1 :(得分:0)

算法不起作用。如果数组中的元素数是偶数,则步骤2可以找到相等数量的0和1。例如,当缺失的数字位于范围的一端或另一端时,就会发生这种情况。

如果数组中的元素数不均匀,则在步骤3之后将进行下一次迭代。

附录

这是一个例子。

设置:0,1,3

在步骤1和2之后,我们有1个LSB = 0和2个LSB = 1。因此,根据步骤2,LSB必须为0.到目前为止,非常好。

在步骤3之后,从LBS = 1的集合中删除值,我们有:

设置:0

在步骤1和2之后,我们有1个LSB'= 0和0 LSB'= 1。因此,根据步骤2,LSB'必须为1.

此时我们已经完成(在删除LSB'= 0的元素后,该集为空),并且已将2识别为答案(LSB'= 1,LBS = 0)。

这是如何运作的?

在每次迭代之后,考虑将数组中的值右移一位以丢弃在前一次迭代中确定的位。这将在数​​组中为除缺失值之外的所有值创建重复项。该算法只是丢弃了这些重复项。