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?
解法一:
依然是brute force的思路。
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> res;
unordered_map<int,int> m;
for(int i=0; i<nums.size(); ++i)
m[nums[i]]++;
for(int i=0; i<nums.size();++i){
if(m[nums[i]]==1) res.push_back(nums[i]);
}
return res;
}
};
解法二:
位操作是个重点。一开始的val其实是两个数字的亦或。val中为1的bit表明这两个数字在该bit上的值不同。这里要注意,val &= -val可以在val中只保留最后边为1的bit。比如11101000,就会得到00001000。于是,如果我们拿val &= -val的结果跟nums中的每一个数字做&运算,就可以把数字分成两组。每一次分别含有一个我们要求的数字。
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> res(2,0);
int val = 0;
for(int i=0; i<nums.size();++i)
val^=nums[i];
val &= -val; //only keep the right 1-bit in val
for(int i=0; i<nums.size();++i){
if(nums[i]&val) res[0]^=nums[i];
else res[1]^=nums[i];
}
return res;
}
};