问题:有一个数组存有1-10亿的乱序整数,其中缺失了一个整数(缺失的用0代替),怎样快速找出缺失的数?
这里给出几种比较简单的方法:
(1)数学技巧法^_^
对给定的数组求和,得到sum1,在具体实现的时候可以一边从磁盘读入数据一边求和,则空间复杂度可以减小至O(1);
然后对1-10亿求和,这里可以使用等差数列求和公式,即s = n*(n+1)/2, 所以sum2 = 1000000000 * (1000000001) / 2。
则缺失整数m = sum1 - sum2 。
整体时间复杂度为求和过程的O(n) 。
具体在实现的时候可以先算出sum1, 然后在遍历中用sum1逐个减去,最后得到的sum1就是缺失的数。
/*查找1-1000000中缺失的数--数学技巧法*/
int FindLostNumber(int *Data, int N) {
long long Sum1 = 0, Sum2 = 0; //这里使用的long long类型在有些环境下会出错,所以可以用double代替
for (int i = 0; i < N; i++) {
Sum1 += Data[i];
}
Sum2 = N * N / 2;
return Sum2 - Sum1;
}
(2)异或运算法^_^
先说明几个需要用到的性质:
① 异或运算具有交换律和结合律。
② 异或连续的整数即1 XOR 2 XOR ... XOR n 有以下规律:
n % 4 == 0 结果为 n
n % 4 == 1 结果为 1