求解数组中唯一出现奇数次的数,很简单。直接 xor 整个数组,偶数次xor为0,只剩下出现奇数次的数的xor。
基于此,假设数组中两个出现奇数次的数为a, b. 对数组xor结果为R,则R = a ^b. 更进一步,R二进制中的每一个1必定只出现在a或b中!
试想如果我们单独考虑R二进制最低位1(具体的十进制值并不关心),然后将数组划分成两个集合,一个集合中的数该位为1,另一个集合该位为0.试想a和b必定不在相同的集合中!且每个集合中只包含一个出现奇数次的数!然后对每个集合xor即可分别得到num1和num2!
求解整数最低位1可使用补码的技巧: low_bit = x ~ -x。 -x 是对二进制 x 取反加1,加1会递推原本 x 在最低位1后面的0,直到恢复 x 最低位1.
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int x = 0;
for (auto v: data) x ^= v;
int low_bit = x & -x;
for (auto v: data) {
if (v & low_bit) *num1 ^= v;
else *num2 ^= v;
}
}
}; 
京公网安备 11010502036488号