题目:
有N+2个数,N个数出现了偶数次,2个数出现了奇数次(这两个数不相等),问用O(1)的空间复杂度,找出这两个数,不需要知道具体位置,只需要知道这两个值。
思想:
(1)我们得拽住特性,偶数次的数异或后都将变成0,如果只有一个奇数,各个数异或后的结果就为该数;
(2)两个不同的数a,b异或后得到c,即c=a^b,其中c必大于0,我们首先找出其中的一个1所在的位数,即找出a,b其中的一个不同位,然后将c与数组中所有该位为1的数进行异或,即得到了其中的一个数x,最后在将x与c异或即得到另一个数;
(3)只涉及到遍历,故时间复杂度为O(n);只涉及到常数个变量,故空间复杂度为O(1)。
程序实现:
#include<stdio.h>
#include<stdlib.h>
int xor_number(int *A, int length, int c)
{
int k = 0;
int temp = c;
while(!(temp&1)){
k++;
temp >>= 1;
}
int i;
for(i = 0; i < length; i++){
if((A[i]>>k)&1)
c ^= A[i];
}
//printf("k:%d\n", k);
return c;
}
int main(void)
{
int A[] = {-9,-9,5,11,3,2,1,-7,1,3,2,3,5,11,11,1,2,5,1,1,3,4,5,2,1,4};
int i;
int c = 0;
//printf("A[]:");
for(i = 0; i < sizeof(A) /sizeof(A[0]) ; i++){
printf("%d ", A[i]);
c ^= A[i];
}
printf("\n");
int a = xor_number(A, sizeof(A) /sizeof(A[0]), c);
//printf("c:%d\n", c);
printf("search numbers a:%d, b:%d\n", a, a^c);
return 0;
}