Such topics are described:
in addition to an array of two numbers appear only once, other figures have emerged twice, asked to identify the two figures as soon as possible.
Requirements: time complexity is O (N), the spatial complexity is O (1).
See my analysis:
the simplification of this question:
an array of a number appears only once, other numbers are in pairs, then we can according to the characteristics XOR operator: A ^ B ^ A = B ; 0 ^ a = a; we can turn all the elements of the array of XOR operation, the end result is a number that occurs only.
I can not see (2019-04-04) day blog
如果这个数组中出现两个不同的数字,而其他数字均出现两次,假设这两个数字分别是x, y。那如果可以将x, y分离到两个数组。这时这道题就变成两个我们简化之后的版本中的数组了。这样问题就可以得到解决了。由于x,y肯定是不相等的,因此在二进制上必定至少有一位是不同的。根据这一位是0还是1可以将x,y分开到A组和B组。并且数组中其他元素也可以根据这个方法划分到两个数组中。这时将两个数组分别做异或运算,结果就是这两个数字。
#include<stdio.h>
#define SIZE(arr) sizeof(arr)/sizeof(arr[0])
void find_num(int *arr, int len,int *num1,int *num2)
{
int i;
int sum = 0;
for (i = 0; i < len; i++)
{
sum^=*(arr + i);//异或出所有数字
}
int j;
for (j = 0; j < sizeof(int)* 8; j++)//int类型数组的字节数32
{
if (((sum >> j) & 1) == 1)//说明sum在右移 j 个单位后,二进制不一样
{
break;
}
}
for (i = 0; i < len; i++)
{
if (((*(arr + i) >> j) & 1) == 1)
{
*num1 ^= (*(arr + i));//异或 j 位置为1的一组数字
}
else
{
*num2 ^= (*(arr + i));//异或 j 位置为0的一组数字
}
}
}
int main()
{
int arr[] = { 1, 3, 5, 7, 1, 3, 5, 9 };
int num1=0, num2=0;
find_num(arr,SIZE(arr),&num1,&num2);
printf("%d %d", num1, num2);
return 0;
}
Summary: simplify complex issues, the two figures appear once divided into two groups appear once the array