目录
1.出现1次的数:其他数字只出现了2次
2.出现一次的两个数字:只有两个数字出现1次,其余都出现两次
3.数组中出现了一次的数字:其他数字出现了k次,一个数出现一次
异或运算:二进制位的每一位相同为0,不同为1
#include<stdio.h> int Search(int* p, int sz) { int s = 0;//0和任何数&都是任何数 for (int i = 0; i < sz; i++) { s ^= *(p + i);//出现了两次的数字&结果是0 } return s; } int main() { int arr[9] = { -1,-2,-3,-4,-2,-3,-4,1,1 }; printf("%d", Search(arr, 9)); return 0; }
方法1:异或
#include<stdio.h> int x = 0, y = 0; int Search(int* p, int sz) { int s = 0; int m = 0; for (int i = 0; i < sz; ++i) { s ^= *(p + i);//最后的结果是两个出现了一次的数字相异或 } while (m < 32) { if ((s >> m) & 1)//找出s里面二进制位是1的某一位 break; else ++m; } for (int i = 0; i < sz; i++)//按照第m位是否是1,将数组元素分为两部分 { if ((p[i] >> m) & 1) x ^= p[i]; else y ^= p[i]; } } int main() { int arr[10] = { 1,2,-1,-2,1,2,-1,-2,9,8 }; Search(arr, 10); printf("%d %d", x, y); return 0; }
方法2: 排序
#include<stdio.h> int x = 0, y = 0; void sort(int* p, int sz) { for (int i = 0; i < sz-1; i++) { for (int j = 0; j < sz - 1 - i; j++) { if (*(p + j) < *(p + j + 1)) { int tmp = p[j]; p[j] = p[j + 1]; p[j + 1] = tmp; } } } } int Search(int* p, int sz) { for (int i = 0; i < sz ; i++) { if ((p[i] != p[i - 1]) && (p[i] != p[i + 1])) printf("%d ", p[i]); } } int main() { int arr[10] = { 1,2,-1,-2,1,2,-1,-2,0,8 }; sort(arr, 10); Search(arr, 10); return 0; }
思路:由于一个数出现了奇数次,所以说使用异或运算就是错误的。
一个数出现了三次,那么它的二进制位就出现了三次,我们将所有的二进制位的每一位累加求和,得到的数字看是不是三的倍数,如果不是,那么所求数x的这一位必定是1,是那么就是0
0101 0101 0101 0111 b[0]=4,b[1]=1,b[2]=4 根据b[i]%k!=0 所以x=0111
#include<stdio.h> int foundOnceNumber(int* arr, int arrLen, int k) { int b[32] = { 0 }; for (int j = 0; j < 32; j++) { int sum = 0; for (int i = 0; i < arrLen; i++) { sum += ((arr[i] >> j) & 1); } b[j] = sum; } //b数组里面存放的是每一个数字的二进制的每一位数字之和 int ans = 0; for (int i = 0; i < 32; i++) { if (b[i] % k != 0) ans += (unsigned int)1<<i; //当数字不是k的倍数时,得到的就是x二进制中为一的那位,左移还原 //1是int类型,当1<<31时,得到的是10000000 00000000 00000000 00000000, //对应 补码是1 00000000 00000000 00000000 00000000,超过了int的范围(2^31-1~-2^31), //所以说强制转换称为无符号类型 } return ans; } int main() {//k表示有多少个数字相同,但是只有一个数字是不同的 int arr[10] = { -2,-2,1,1,4,1,4,4,-4,-2 }; printf("%d", foundOnceNumber(arr, sizeof(arr), 3)); }