136. 只出现一次的数字
- 任意两个相同的数字进行异或操作结果为0
- 任何数与0进行异或操作结果还是原来的数
根据上面这两个定理,由于其他数字都出现了两次,那么这些数字进行异或操作的结果就是0,最后的答案就是出现一次的数字
class Solution {
public int singleNumber(int[] nums) {
int ans=0;
for(int num:nums){
ans^=num;
}
return ans;
}
}
137. 只出现一次的数字 II
数字是整型,二进制有32位,因此统计出各个bit位上面的1有多少个,个数%3剩下的1的个数就只出现1次的数字的改bit位上的1
class Solution {
public int singleNumber(int[] nums) {
int[] cnt=new int[32];
for(int i=0;i<32;i++){
for(int num:nums){
cnt[i]+=((num>>i)&1);
}
}
int ans=0;
/*
给出一个bit数组cnt cnt[0]表示最低位是1还是0 cnt[31]表示最高位是1还是0
根据bit位数组还原数字n
从最高位开始 每次进行两次操作: 先左移一位 然后和比特位值进行或操作
*/
for(int i=31;i>=0;i--){
ans<<=1;
ans|=cnt[i]%3;
}
return ans;
}
}
260. 只出现一次的数字 III
class Solution {
public int[] singleNumber(int[] nums) {
//假设只出现1次的两个数为a,b
int xor=0;
for(int num:nums){
xor^=num;
}
//进行异或操作后 xor=a^b
int mask=xor&(~xor+1);//mask获取xor最右边的1 比如xor右边第2位是1 则xor=0000...10
//mask只有一个bit位为1 其他都是0 记作是第k位为1
//a b的第k位肯定一个是1 一个是0 不妨认为a的第k位是1 b的低k位是0
//根据第k位是否为0将所有的数字分为两组 设第k为为1的划分到a组
//a组中的数字肯定是奇数 其余数字都出现两次+数字a
//因此可以求出a 又因为xor=a^b 所有a^xor=b
//至此求的a b
int a=0;
for(int num:nums){
if((num&mask)!=0){//num的第k位是1 分到a组
a^=num;
}
}
return new int[]{a,a^xor};
}
}