题意:给你一组数,里面有两个数仅出现一次,而其余的数则出现两次。要求在O(N)的时间复杂度和O(1)的空间复杂度内找出这两个数。
解题思路:两个相同的数异或操作会变0,先将数组中所有的数全异或,结果肯定不等于0,两个仅出现一次的数异或不为0。将得到的数取出一个不为0的位,那么根据该位可以将这个数组分成两部分:将该位与操作等于0,和将该位与操作不等于0的两类数,将这两类数分别于操作即可得到这两个数。
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int tmp = 0;
for(int i = 0; i < nums.size(); i++)
tmp ^= nums[i];
int flg = 1;
while((tmp & flg) == 0)
flg <<= 1;
int a1 = 0;
for(int i = 0; i < nums.size(); i++)
if((nums[i] & flg) != 0)
a1 ^= nums[i];
return {a1, tmp ^ a1};
}
};
注意:
第一、按位操作(与或非)操作符优先级比逻辑比较运算符(==,!=)更低,所以需要试用括号。
第二、找到某数的从右到左第一个不为0的位的数的方法是
int flg = 1;
while((tmp & flg) == 0)
flg <<= 1;