题目:
一个数组里,除了三个数是唯一出现的,其余的都出现偶数个,找出这三个数中的任一个。比如数组元素为【1, 2,4,5,6,4,2】,只有1,5,6这三个数字是唯一出现的,我们只需要输出1,5,6中的一个就行。
由上篇博客我们可以清楚的想到,首先要使用异或去重,因为现在是 3 个出现1次的正整数,所以肯定存在 1 位 使得 这三个数分在两组,一组有两个出现1次的数据,另一组有1个出现1次的数据,这样我们将这个出现1次的数据输出即可,我们这里采用依次遍历二进制位( 0 ~ 31 位),直到找到出现出现1次的数据,这样很轻松就可找到三个数中任意一个了,
理解解题方法的关键点是:根据 不同 整数二进制表示形式 肯定至少有一位不同,根据这个不同的位 分成两组。
代码如下:
#include <stdio.h> //得到第i位的二进制 #define isON(n, i) ((n) & 1 << (i)) // Author: 397090770 // E-mail: [email protected] // 转载请注明出处 void findTheSingleNumber(int *arr, int size){ int tempA = 0, tempB = 0; int countA = 0, countB = 0; int i = 0, j = 0; for(i = 0; i < 31; i++){ //32位平台上,int只有32位 tempA = tempB = countA = countB = 0; for(j = 0; j < size; j++){//遍历数组 if(isON(arr[j], i)){ tempA ^= arr[j]; countA++; }else{ tempB ^= arr[j]; countB++; } } if(countA & 0x1){//奇数 if(0 == tempB){ continue; }else{ printf("%d\n", tempA);//肯定是不同的数字 break; } }else{ if(0 == tempA){ continue; }else{ printf("%d\n", tempB); break; } } } } int main(){ int arr[] = { /*1, 3, -9, 2, 1, 2, -10*/ 1, 2,4,5,6,4,2 }; findTheSingleNumber(arr, sizeof(arr) / sizeof(arr[0])); return 0; }