我在麻省理工大学的书籍介绍算法第二版中有以下问题
问题在于
阵列A [1。 。 n]包含从0到n的所有整数,除了一个。这很容易 通过使用辅助数组B [0来确定O(n)时间内缺失的整数。 。 N] 记录哪些数字出现在A.但是,在这个问题上,我们无法访问 A中的整数,只需一个操作。代表A的元素 在二进制文件中,我们可以用来访问它们的唯一操作是“获取第j位” A [i],“需要不断的时间。
显示如果我们只使用此操作,我们仍然可以在O(n)时间
中确定缺失的整数
请帮助
答案 0 :(得分:6)
拨打您丢失的号码M
。
根据A[i]
的最低有效位是1还是0,您可以将数组拆分为两部分。两部分中较小的一部分(称为P_1
)最多为{ {1}}元素的大小,它会告诉您(n-1)/2
的最低有效位是1还是0。
现在考虑M
元素的第2位。同样,这部分可以分成两部分,两部分中较小的一部分(P_1
)告诉你这个位是1还是0。
继续前进(P_2
,P_3
,...),直到找出所有位数为止。
您可以证明这是P_4
,因为您实际上是在查看数组中O(n)
个不同的位,并且此总和小于n + n/2 + n/4 + ...
。
答案 1 :(得分:3)
这是一个Python实现:
def bit_at(n, bit):
return (n>>bit) & 1
def find_missing(a, bits):
indexes = range(len(a))
missing = 0
for bit in range(bits):
ones = [i for i in indexes if bit_at(a[i], bit)==1]
zeroes = [i for i in indexes if bit_at(a[i], bit)==0]
if len(ones) <= len(zeroes):
indexes = ones
missing |= (1<<bit)
else:
indexes = zeroes
return missing
print find_missing([7,2,6,4,1,5,0], 3)