以下是我正在寻找答案的问题:
数组A [1 ... n]包含从0到n的所有整数,除了一个。确定失踪很容易 通过使用辅助数组B [0 ... n]记录哪些数字出现在A中,在O(n)时间内整数。在此 但问题是,我们无法通过单个操作访问A中的整个整数。 A的元素是 以二进制表示,我们可以用来访问它们的唯一操作是“获取A [i]的第j位”,其中 需要不断的时间。 证明如果我们只使用这个操作,我们仍然可以在O(n)时间内确定缺失的整数。
我有这种方法: 如果我没有上述限制,我会把所有的数字都加在一起并对它们进行异或。然后将结果与1..n中的所有数字进行异或。结果就是我的答案。 在这个问题中,类似地,我可以对于数组中的所有元素,在log(n + 1)位的距离处重复XOR不同数字的位,然后将它们与元素1 ... n进行异或,但复杂性出现了在我看来是O(nlogn)。
如何实现O(n)复杂度? 感谢
答案 0 :(得分:1)
您可以使用radix sort的变体:
根据MSb(最高位)对数字进行排序
你得到两个大小为n / 2,n / 2-1的列表。您可以使用n / 2个元素“删除”列表 - 缺少的数字不存在。
重复第二个MSb,依此类推。
最后,您选择的“路径”(每个位的列表较小的位)将代表缺失的数字。
复杂性为O(n + n/2 + ... + 2 + 1)
,自n + n/2 + .. + 1 < 2n
起 - 这是O(n)
为简单起见,这个答案假设n=2^k
为某个整数k
(这种放松可以在以后放弃,通过为MSb执行s'特殊'句柄)。
答案 1 :(得分:0)
你有n个整数范围[0..n]。您可以检查每个数字的最高位,并将这些数字分成C组(MSB 0)和D组(MSB 1)。由于您知道范围是[0..n],因此可以计算此范围内MSB 0的数量,称为S1,以及此范围内MSB 1的数量,称为S2。如果C的大小不等于S1,那么你知道缺少的数字有MSB 0.否则,你知道缺少的数字有MSB 1.然后,你可以递归地解决这个问题。由于每个递归调用都需要线性时间,并且除第一个递归调用之外的每个递归调用都可以将问题大小减半,因此总运行时间是线性的。