136. 只出现一次的数字
异或:相同为0,不同为1,两个相同的数字异或后得0
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res = 0;
for(auto c : nums) res ^= c;
return res;
}
};
137. 只出现一次的数字 II
从二进制中的每一位去考虑
/*
都在说用异或等等的,提供另外一种容易理解的思路,将每个数想象成32位的二进制,
对于每一位的二进制的1和0累加起来必然是3N或者3N+1, 为3N代表目标值在这一位没贡献,3N+1代表目标值在这一位有贡献(=1),
然后将所有有贡献的位|起来就是结果。这样做的好处是如果题目改成K个一样,只需要把代码改成cnt%k,很通用
*/
class Solution {
public:
int singleNumber(vector<int>& nums) {
// 位运算
int ans = 0;
for(int i=0;i<32;i++)
{
int sum = 0;
for(auto c : nums) sum += c >> i & 1;
ans |= (sum % 3) << i;
}
return ans;
}
};
260. 只出现一次的数字 III
分组异或,题解
技巧:1:一个整数对自己的负数进行与操作(&)就能仅保留最右侧的1。 2:根据异或的性质,如果有 a ^ b = c, 则有a^c = b
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
long long bit_mask = 0; // 记得初始化为0
for(auto c:nums) bit_mask ^= c;
int d = bit_mask & (-bit_mask); // 不改longlong,-2147483648转正爆int
int v1 = 0; // 记得初始化为0
for(auto c : nums)
if(c & d) v1 ^= c;
return {v1,(int)bit_mask ^ v1};
}
};