题目:
Given an array of numbers nums
, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
For example:
Given nums = [1, 2, 1, 3, 2, 5]
, return [3, 5]
.
Note:
- The order of the result is not important. So in the above example,
[5, 3]
is also correct. - Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
主要思想:两个只出现一次的数字必定有某一位不同
一、循环(for(int i = 0; i < 31; i++)),根据第i位是否为1将数据分成两组,再判断两组的数目是否为奇数,为奇数则第i位即这两个数第一位不同的位;
二、现将所有数据进行异或,那么结果为这两个数字的异或,找到这个结果中第一位不位0的位,该位即两个数字第一位不同的位,然后再将所有数据根据该位是否为1分成两组,两个数字即分别位于一组,各组异或结果即这两个数字。
class Solution {
public:
// Is the indexBit bit of num 1?
bool IsBit1(int num, unsigned int indexBit)
{
num = num >> indexBit;
return (num & 1); //num&1<<indexBit
}
// Find two numbers which only appear once in an array
// Input: data - an array contains two number appearing exactly once,
void FindNumsAppearOnce(vector<int>& data, int length, int &num1, int &num2)
{
if (length < 2) return;
for(int i = 0; i < 31; i++){ //32位平台上,int只有32位
num1 = num2 = 0;
int tempA =0,tempB =0,countA=0,countB=0 ;
for(int j = 0; j < length; j++){//遍历数组
if(IsBit1(data[j], i)){ //第i位只有是1和不是1两种情况,两个只出现奇数次的数必定有某一位不同
num1 ^= data[j];
countA++;
}
else{
num2 ^= data[j];
countB++;
}
}
if((countA & 0x1)&&(countB & 0x1)){//奇数 只有两组数都为奇数时,才说明两个只出现一次的数字被分在了不同的组
break;
}
}
}
vector<int> singleNumber(vector<int>& nums) {
int x,y;
vector<int> res;
FindNumsAppearOnce(nums,nums.size(),x,y);
res.push_back(x);
res.push_back(y);
return res;
}
};
unsigned int FindFirstBitIs1(int num)
{
int indexBit = 0;
while (((num & 1) == 0) && (indexBit < 32))
{
num = num >> 1;
++ indexBit;
}
return indexBit;
}