一个单身狗
一个数组中只有一个数字是出现一次,其他所有数字都出现了两次。
编写一个程序找出这个只出现一次的数字。
方法1(异或)
- a ^ a = 0
- a ^ 0 = a
- ^满足结合律
#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,4,2,3,5};int i = 0;int ret = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){ret = ret ^ arr[i];} printf("单身狗:%d\n", ret);return 0;
}
方法2(暴力求解法)
#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,4,2,3,5 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){int count = 0;int j = 0;for (j = 0; j < sz; j++){if (arr[i] == arr[j]){count++;}}if (1 == count){printf("单身狗:%d\n", arr[i]);break;}}return 0;
}
两个单身狗
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
假设是1, 2, 3, 4, 5, 6, 4, 3, 2, 1
思路:只要是不同的数,异或后肯定有1,是1的那个二进制位不相同
所以我们可以把它们分成两组(按照5和6二进制某一位的不同)
十进制 | 二进制 |
---|---|
5 | 101 |
6 | 110 |
比如:
拿最后一位分组:
1 1 3 3 5 (最后1位是1)
2 2 4 4 6 (最后1位是0)
拿倒数第二位分组:
1 1 4 4 5 (是0)
2 2 3 3 6 (是1)
过程:
1.全部异或在一起
2.计算第几位是1
3.分组
#include<stdio.h>
void dog2(int arr[], int sz)
{int ret = 0;int i = 0;//1.全部异或在一起for (i = 0; i < sz; i++){ret ^= arr[i];}//2.计算ret第几位是1,得到posint pos = 0;for (i = 0; i < 32; i++){if (((ret >> i) & 1) == 1){pos = i;break;}}//3.分组int s1 = 0;int s2 = 0;for (i = 0; i < sz; i++){if (((arr[i] >> pos) & 1) == 1)s1 ^= arr[i];elses2 ^= arr[i];}printf("单身狗1是%d\n单身狗2是%d", s1, s2);
}
int main()
{int arr[] = { 1,2,3,4,5,6,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);dog2(arr, sz);return 0;
}