【剑指offer】数组中只出现一次的数字
题目链接:数组中只出现一次的数字
题意:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
题解:
1、我最开始想到用map去统计一下。第一次出现这个数字后标记这个位置,再从当前位置向后找第二个出现1次的数字。
2、后面想到用set,好像也是差不多。。
3、正解是异或。出现偶数次的数字,异或自己肯定是0。整个数组异或完肯定是只有那出现一次的两个数的结果。再找到其中一个数提供1这个bit位,就能找到这两个数字。
代码:
1 class Solution { 2 public: 3 void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { 4 5 map<int,int> mp; 6 int len = data.size(); 7 for( int i = 0; i < len ;i++){ 8 mp[data[i]]++; 9 } 10 int flag; 11 for(int i = 0; i < len ;i++){ 12 if(mp[data[i]]==1){ 13 *num1 = data[i]; 14 flag = i; 15 break; 16 } 17 } 18 for(int i = flag+1; i < len ;i++){ 19 if(mp[data[i]]==1){ 20 *num2 = data[i]; 21 break; 22 } 23 } 24 25 } 26 }; 27 28 29 OR 30 31 32 class Solution { 33 public: 34 void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { 35 set<int> ss; 36 set<int>::iterator it; 37 int len = data.size(); 38 for(int i = 0; i < len ;i++){ 39 if(ss.find(data[i]) == ss.end()) 40 ss.insert(data[i]); 41 else{ 42 it = ss.find(data[i]); 43 ss.erase(it); 44 } 45 } 46 it = ss.begin(); 47 *num1 = *it; 48 *num2 = *(++it); 49 } 50 }; 51 52 OR 53 54 class Solution { 55 public: 56 int FindBit(int num){ //二进制数里第一个为1的位数 57 int index = 0; 58 while((num&1) == 0 && (index < 8*sizeof(int))){ 59 num = num>>1; 60 index++; 61 } 62 return index; 63 } 64 //判断index上bit位是否为1 65 bool isbit(int num ,int index){ 66 num = num>>index; 67 return (num&1); 68 } 69 void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { 70 int len = data.size(); 71 if(len < 2) return; 72 int res = 0; //数组异或结果 73 for(int i = 0; i < len ; i++) res ^= data[i]; 74 75 int num = FindBit(res); 76 *num1 = 0; *num2 = 0; 77 for(int i = 0; i < len; i++){ 78 if(isbit(data[i],num)) *num1^=data[i]; 79 else *num2 ^=data[i]; 80 } 81 } 82 };