利用异或的特性
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;
}
};