一、题目描述
一个整型数组 nums
里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
二、分析过程
1,先定义一个变量ret = 0,让它与数组中的数字进行异或(^),这时会得到一个数组中两个不相同数字异或的结果;
对示例1来说:异或二进制位相同为0,相异为1,0与任何数异或都得任何数,对示例1异或之后得结果为1和6异或之后的结果;在这本应有32个bit位,我就写后面4位,1的二进制位0001,6的二进制位0110,异或完之后的结果为0111,转化为十进制为7。
2,对异或完之后的数字从地位向高位找第j为为1时j的值;
3,将原数组分为2组,假设第j位1的在a组,第j位为0的在b组;
4,再定义两个变量,int x = 0, int y = 0,方便异或,对其x和y让其分别进入a组或b组,原数组中的其他数字要么进入a组,要么进入b组;
5,那么最后a组和b组最后就分成了a组中其它数字出现2次,只有1个数组出现一次,同理b组也是。
三、代码演示
#include<stdio.h>
#include<stdlib.h>
int* Find_Two_number(int* nums, int sz) {
int ret = 0;
for (int i = 0; i < sz; i++) {
ret ^= nums[i];
}
int j = 0;
for (; j < 32; j++) {
if (ret & (1 << j))
break;
}
int x = 0;
int y = 0;
for (int i = 0; i < sz; i++) {
if (nums[i] & (1 << j)) {
x ^= nums[i];
}
else
{
y ^= nums[i];
}
}
int* arr1 = (int*)malloc(sizeof(int) * 2);
arr1[0] = x;
arr1[1] = y;
return arr1;
}
int main() {
int arr[] = { 1,2,10,4,1,4,3,3 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = Find_Two_number(arr, sz);
for (int i = 0; i < 2; i++) {
printf("%d ", p[i]);
}
free(p);
p = NULL;
return 0;
}
四、运行结果截图