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?
step1. 对所有数做异或,得到x^y.
step2. 由于x^(x^y) = y, y^(x^y)=x. 找到区别x和y的子集,做异或即可。
step3.通过在x^y找到取1的标志位来区别x和y的子集。
这里有个小技巧:
n&(n-1)作用:将n的二进制表示中的最低位为1的改为0,先看一个简单的例子:
n = 10100(二进制),则(n-1) = 10011 ==》n&(n-1) = 10000
可以看到原本最低位为1的那位变为0。
n = 10100(二进制),则(n-1) = 10011 ==》n&(n-1) = 10000
可以看到原本最低位为1的那位变为0。
利用n&(~(n-1))找到最低位的1.
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int temp = 0 ;
for(int i=0; i<nums.size(); ++i){
temp ^= nums[i];
}
int mask = temp&(~(temp-1)); //找出第一个区别x,y的bit位,就是mask中的第一个1的位置。其他位置的操作让mask值0.
int x = 0;
int y = 0;
for(int i=0; i<nums.size(); ++i){
if(nums[i]&mask){ //含有x和其他重复数字的子集
x ^= nums[i];
}
else{
y ^= nums[i]; //含有y和其他重复数字的子集
}
}
return vector<int> {x,y};
}
};