这与第5版Cracking the coding面试中的问题5.7(在Bit Manipulation下)有关(如果问题不适合SO,请让我知道正确的网站,我会移动它):< / p>
数组A [1..n]包含从0到n的所有整数,除了一个 丢失的号码。在这个问题上,我们无法访问整个 A中的整数,只有一个操作。 A的元素是 以二进制表示,是我们可以用来访问的唯一操作 它们是“获取A [i]的第j位”,这需要恒定的时间。写 用于查找缺少的整数的代码。你能在O(n)时间内完成吗?
应用的算法是:
有人可以解释第3步背后的逻辑吗?它基本上从当前列表中删除所有奇数/偶数(取决于找到的缺失数字的位),并在下一次迭代中使用修改后的列表。我们为什么要这样做?
答案 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)。
这是如何运作的?
在每次迭代之后,考虑将数组中的值右移一位以丢弃在前一次迭代中确定的位。这将在数组中为除缺失值之外的所有值创建重复项。该算法只是丢弃了这些重复项。