题目描述:
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?
使用位操作。首先把数组nums划分为两部分,每一部分包含一个只出现一次的元素。然后对每一部分进行异或操作即可得到只出现一次的元素。
把数组划分为两部分的方法:考虑到数组nums中只有两个元素出现的次数为1,其它的都是两次,因此对nums中的所有元素进行异或操作,得到的结果xor_result即为只出现一次的两个元素的异或的结果(因为两个相同元素的异或结果为0)。由于数组nums中有两个只出现一次的元素,因此xor_result的二进制肯定有一位为1(该位即为只出现一次的两个元素不同的一位),选定任意一位并依据该二进制位是否为1把数组nums划分为两部分,这样就把数组nums划分为了两部分,每一部分包含一个只出现一次的元素。
AC代码如下:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
vector<int> res;
int n = nums.size();
if (n == 0) return res;
int xor_result = 0;
for (int i = 0; i < n; ++i){
xor_result ^= nums[i];
}
int idx = 0;
for (int i = 0; i < sizeof(int) * 8; ++i){
if (xor_result&(1 << i)){
idx = i;
break;
}
}
int num1 = 0;
int num2 = 0;
for (int i = 0; i < n; ++i){
if (nums[i] & (1 << idx)){
num1 ^= nums[i];
}
else{
num2 ^= nums[i];
}
}
res.push_back(num1);
res.push_back(num2);
return res;
}
};