思路:异或满足交换律,第一步异或,相同的数其实都抵消了,剩下两个不同的数。这两个数异或结果肯定有某一位为1,不然都是0的话就是相同数。找到这个位,不同的两个数一个在此位为0,另一个为1。按此位将所有数分成两组,分开后各自异或,相同的两个数异或肯定为0(而且分开的时候,两个数必为一组)。剩下的每组里就是我门要找的数。
class Solution {
public:
vector<int> findNumsAppearOnce(vector<int>& nums) {
int two_xor = 0;
for (int x : nums) //所有数异或一遍,重复数字双双抵消
two_xor ^= x; //剩下的是两个不同数字的异或值
int mask = two_xor & (-two_xor); //lowbit算法得到该数二进制最低的非零位
int a = 0, b = 0;
for (int x : nums)
{
//注意这里要么写(x & mask)要么写((x & mask) == mask),不能写((x & mask) == 1)
if (x & mask) a ^= x; //用这个非零位将整组数分为a,b两组分别异或
else b ^= x;
}
return {a, b};
}
};