我最近有一位朋友向我汇报,在求职面试时他被问到以下问题,这个问题似乎很受欢迎:
您将获得一个列表L[1...n]
,其中包含从0到n的所有元素,除了一个。此列表的元素以二进制and are not given in any particular order
表示,我们可以用来访问它们的唯一操作是在常量时间内获取L [i]的第j位。
如何找到O(n)
中缺少的号码?
他能够回答这个问题(我相信有多个解决方案,其中没有一个太复杂)。例如,以下伪代码解决了上述问题:
Say all numbers are represented by k bits and set j as the least significant bit (initially the rightmost).
1. Starting from j, separate all the numbers in L into two sets (S1 containing all numbers that have 1 as its jth bit, and S2 containing all numbers that have 0 in that position).
2. The smaller of the two sets contains the missing number, recurse on this subset and set j = j-1
在每次迭代中,我们将集合的大小减半。所以最初我们有O(n),然后是O(n / 2),O(n / 4)...... = O(n)
然而,后续问题是:"如果我们现在列表L中缺少 k 号码,我们希望报告所有 k 号码仍然保持O(n)复杂性和初始问题的局限性?怎么做?
有什么建议吗?
答案 0 :(得分:1)
bool J[1..n + 1]={false,false...}
int temp;
for(i = 1; i <= n; i++)
{
temp=bitwisecopy of L[i];
J[temp + 1]=true
}
for(i = 1; i <= n+1; i++)
{
if(J[i]==false)
print i + 1;
}
Lol认为它的主旨......我认为指数可能搞砸了。
我是否正确理解了问题?我并不是很清楚,唯一的操作是什么意思才能访问L [i]的第j位。
答案 1 :(得分:0)
你可以通过对数组执行线性遍历来解决O(n)中的原始问题,直到找到与预期值不匹配的数字,就像这样(是的,我知道我正在使用数组ints近似比特数组,但概念是相同的):
int[] bits = {1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0};
int bitIndex = 0;
for (int num = 1; num < Integer.MAX_VALUE; num++) {
int numBits = (int) (Math.log(num) / Math.log(2)) + 1;
int nextNum = 0;
for (int index = 0; index < numBits; index++) {
nextNum = (nextNum << 1) | bits[bitIndex + index];
}
if (nextNum != num) {
System.out.println("Missing number: expected=" + num + ", actual=" + nextNum);
break;
}
bitIndex += numBits;
}
如果要在保持O(n)运行时的同时打印阵列中不存在的所有数字,只需将break;
替换为num = nextNum;
即可继续检查下一个数字。< / p>
虽然这种方法存在一些潜在的问题。如果缺少多个连续号码,则所有投注均已关闭。此外,如果num + 1
中的位数大于num
中的位数,并且位数组中缺少num
,则位索引将与...不一致数据
当然,如果允许丢失多个号码,那么问题就无法解决。考虑例如:
{1,1,1,1,1,1,1}
在这种情况下同样有效的是说我有数字1,3和15,因为它说我只有127或者我有7和15.当允许多个连续值丢失时,解析位的方法基本上变得随意。
所以也许回答第二个问题的一种方法是将所有位读成一个大整数,并说“你有[非常大的数字],并且它之前的所有数字都丢失了”。然后你在O(n)时间内产生了一个有效的答案。
答案 2 :(得分:0)
我的想法是通过以下方式解决它:
假设2 ^ M是2的最低幂,高于N:
2^M>N, 2^M-1 <= N
现在查看从1到2 ^ M-1的所有数字,并在所有数字之间进行按位异或 (因为你每次只能分别对每个数字进行比特来检查它 - 它是相同的)
所有XOR的结果将是您要查找的数字。
例如:如果N = 6,则缺少的数字是3:
M=3 => 2^M-1=7 =>
1 XOR 2 XOR 4 XOR 5 XOR 6 XOR 7 = 3