【思路】
从一系列的数字中找出两个只出现过一次的数,其它数字只出现过两次,这里我们可以得出结论,所有的数字求位运算异或操作之后所得的结果跟这两个数字的异或结果必定相同,由于这两个数字是不同的,它们的异或结果肯定不为0,例如以下:
[1,5,5,3,4,6,1,4]
1 xor 5 xor 5 xor 3 xor 4 xor 6 xor 1 xor 4 = 3 xor 6 = 5 = 101(二进制)
那么,如果取101的最低位1作为划分界限,根据数字对应位是否包含1分别进行位运算求异或,就可以求出这两个数字,记作a和b,求法如下:
101 -> 001
初始化 a = 0, b = 0, a和b分别代表数字二进制对应位是1的异或结果、数字二进制对应位是0的异或结果
1 & 001 != 0, a = a xor 1 = 1
5 & 001 != 0, a = a xor 5 = 4
5 & 001 != 0, a = a xor 5 = 1
3 & 001 != 0, a = a xor 3 = 2
4 & 001 == 0, b = b xor 4 = 4
6 & 001 == 0, b = b xor 6 = 2
1 & 001 != 0, a = a xor 1 = 3
4 & 001 == 0, b = b xor 4 = 6
至此,a = 3,b = 6
【代码】
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int size = nums.size();
int xorNum = 0;
for (int i=0; i<size; i++)
xorNum ^= nums[i];
xorNum = xorNum&(-xorNum); // 以二进制最低位的1作为划分界限
int a = 0, b = 0;
for (int i=0; i<size; i++) {
if ((nums[i]&xorNum) == 0) // 二进制对应位是0的情况
a ^= nums[i];
else // 二进制对应位是1的情况
b ^= nums[i];
}
return vector<int>{a,b};
}
};