题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
思路如下:
1. 使用map结构保存每个数字出现的次数
2. 两个相同的数字异或,结果为0
如果将左右数字都异或,结果必然是那两个只出现一次数字的异或
根据异或的结果, 找到区分两个数字的特征,就可以将数字分成两组,分别异或
本题区分两个数字的特征可以取 两个数字异或的结果中最右边一位为1
代码如下:
class Solution {
public:
//方法一:依次遍历 使用map保存每个数字出现的次数
void find_appearonce_number_map(vector<int>& data,int* num1,int *num2){
map<int, int> mp;
for(int i = 0; i < data.size(); i++){
mp[data[i]]++;
}
int index = 1;
for(int i = 0; i < data.size(); i++){
if(1 == mp[data[i]]){
if(1 == index){
*num1 = data[i];
index++;
}
else{
*num2 = data[i];
}
}
}
}
//方法二:两个相同的数字异或结果为0 将所有数字异或 结果为只出现依次的两个数字的异或
// 取异或结果的第一个为1的位, 将数组分为两组,分别异或
void find_appearonce_number_xor(vector<int>& data,int* num1,int *num2){
int ret = 0;
for(int i = 0; i < data.size(); i++){ //所有数字异或
ret ^= data[i];
}
int index = 1;
while(0 == (index & ret)){ //取第一个为1的位
index = index << 1;
}
for(int i = 0; i < data.size(); i++){
if(0 == (index & data[i])){ //将数字分为两组 第index位为0的一组
*num1 ^= data[i];
}
else{ //第index位为1的一组
*num2 ^= data[i];
}
}
}
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
//find_appearonce_number_map(data, num1, num2);
find_appearonce_number_xor(data, num1, num2);
}
};