剑指 Offer 56 - I. 数组中数字出现的次数
因为一定存在两个不同的数,转换成二进制,两个不同的数一定会有相同的位上不同为1,其余相同的数异或为0,先取整体异或和,然后找到任意一个位上的1,这个1一定来自两个不同的数中间的一个,再然后通过循环来遍历和这个位置的1相与,相与为1则异或a,否则异或b,a和b则是这两个不同的数
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int fs=0;
for(int i=0;i<nums.size();i++) fs^=nums[i];
int p=1;
while(!(p&fs)){
p<<=1;
}
int a=0;
int b=0;
for(int i=0;i<nums.size();i++){
if(p&nums[i]) a^=nums[i];
else b^=nums[i];
}
vector<int>ans;ans.push_back(a);
ans.push_back(b);
return ans;
}
};
剑指 Offer 56 - II. 数组中数字出现的次数 II
循环过程中计算1的个数除三取余,因为只有一个数不同,所以最后结果two不可能为1,因此只需要返回ones
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ones=0;
int twos=0;
for(auto num:nums){
ones = ones^num & ~twos;
twos = twos^num & ~ones;
}
return ones;
}
};
参考https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/solution/ji-yu-krahetsda-lao-gei-chu-de-you-xian-67dkc/