某数组A[1...n]含有所有从0到n的整数,但其中有一个整数不在数组中。通过利用一个辅助数组B[0...n]来记录A中出现的整数,很容易在O(n)时间内找出所缺的整数。但如果A中的元素是以二进制表示的,我们所能用的唯一的操作就是取A[i]的第j位。
第一种以十进制的代码,是利用一个辅助数组来进行计数,然后扫描辅助数组,从而来确定所缺少的数字:
#include<iostream>
using namespace std;
int main()
{
cout << "Please enter the range of the numbers:";
int range; //输入数字范围
cin >> range;
int *A = new int [range]; //建立输入数组
int *B = new int [range + 1];//建立辅助数组
for(int i = 0;i <= range;i++){
B[i] = 0;
}
int i = 0;
int temp;
cout << "Please enter the number you have:";
while(cin >> temp && i < range){
A[i] = temp;
i++;
}
int j = 0;
while(j < i){
B[A[j]]++;
j++;
}
for(i = 0;i <= range;i++){
if(B[i] == 0)
cout << i << " ";
}
cout << endl;
return 0;
}
B[A[j]]++;
j++;
}
for(i = 0;i <= range;i++){
if(B[i] == 0)
cout << i << " ";
}
cout << endl;
return 0;
}
关于二进制的,我只做到了时间复杂度是O(nlgn),而书上却说能做到O(n)的时间复杂度。。。
首先存储模式,我用的是二维数组。通过二进制数的性质我们可以知道,二进制数的长度为(lgn) + 1(计算机中lg我默认以2为低)。为了计算方便,我将所有的数的二进制全部都扩容成(lgn) + 1的长度,这样,二维数组消耗总的存储空间为nlgn。
接下来,可以利用将二进制数转化为十进制数的思想。我们知道,将2进制数转化为十进制数的方法为:
以右端为起始位,记为n = 1,该位上的数字i(i=0或1),共计有m位,将十进制数记为d,则d=∑(n = 1在下,m在上)i * 2 ^ ( n - 1 )【数学公式写不好。。。求各位看官海涵】
我们将二位数组每一列上的数字相加,得到该列的和,并存储。依次进行(lgn) + 1次,然后根据上面的公式,利用牛顿多项式求和方法,来减少乘法的运算次数。得出和。
而通过计算,我们可以知道完整的序列求和的结果。因此,想减后,得到了缺少的一个数字。
注意,这个方法的局限性在于,只能缺少一个数字的情况下使用,如果多个数字,还是要逐行求出十进制数,然后借助辅助数组进行筛选,与上方代码的方法类似,只是多了一个将二进制数转化为十进制数的步骤。
二进制寻找:
#include<iostream>
#include<cmath>
using namespace std;
void bin(int **A,int i,int row,int col)
{
while(i != 0)
{
A[row][col] = i % 2;
i /= 2;
col--;
}
return;
}
int main()
{
cout << "Please enter the range of the numbers:";
int range; //输入数字范围
cin >> range;
int col = log(range) / log(2) + 1;
int **A = new int * [range + 1]; //建立输入数组
for(int i = 0;i <= range;i++){
A[i] = new A[col];
}
for(int i = 0;i <= range;i++){
for(int j = 0;j < col;j++)
A[i][j] = 0;
}
int i = 0;
int temp;
cout << "Please enter the number you have:";
while(cin >> temp && i < range){
bin(A,temp,i,col);
i++;
}
for(i = 0;i < col;i++)
for(int j = 0;j < range;j++)
A[range][i] += A[j][i];
int result1 = A[range][0];
for(i = 0;i < col - 1;i--){
result1 = 2 * result1 + A[range][i+1];
}
int result2 = 0;
for(i = 0;i <= range;i++)
result2 += i;
int target = result2 - result1;
cout << "所缺的数是:" << target << endl;
cout << endl;
return 0;
}