利用异或的特性
1. a ^ a = 0
2. a ^ 0 = a
3. a = a ^ b ^ b
题目一、数组中唯一只出现一次的数字
一次异或,得到最后的数字即为答案
int FindOnceNum(int arr[], int len) { if (arr == NULL || len <= 0) return -1; int ret = 0; for (int i = 0; i<len; i++) { ret = ret^arr[i]; } return ret; }
题目二、数组中有2个只出现1次的数字
2,4,3,6,3,2,5,5
假设只出现1次的两个数字分别为a,b;则最后结果分别为c = a^b;
如题,异或结果为0010,则按照倒数第二位为1或者0将数组分为{2,3,6,3,2}和{4,5,5}
分别异或可得;
基于map的实现
class Solution { public: void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) { map<int, int> hashMap; for (int i = 0; i < data.size(); i++) { if (hashMap.count(data[i])) hashMap[data[i]]++; hashMap.insert(make_pair(data[i], 1)); } auto piter = hashMap.begin(); bool first = false; while (piter !=hashMap.end()) { if (1 == piter->second && first == false) { *num1 = piter->first; first = true; } if (1 == piter->second && first == true) { *num2 = piter->first; } ++piter; } } };
基于异或运算的实现
class Solution { public: void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) { int len = data.size(); int res = FindOnceNum(data, len); unsigned index = FindFirstBitIs1(res); *num1 = 0, *num2 = 0; for (int i = 0; i < len; i++) { if (!BitIs1(data[i], index)) *num1 = *num1^data[i]; else *num2 = *num2^data[i]; } } unsigned FindFirstBitIs1(int num) //右边第几位是1 { unsigned index = 0; while (!(num & 1) && index <= 8 * sizeof(int)) { num = num >> 1; ++index; } return index; } bool BitIs1(int num, int index)//右边数第index是不是1 { num = num >> index; return (num & 1); } int FindOnceNum(vector<int> arr, int len) { if ( len <= 0) return -1; int ret = 0; for (int i = 0; i<len; i++) { ret = ret^arr[i]; } return ret; } };