常见的位运算
x & 1 == 0 //判断奇偶
x & (x - 1) //清除最右边的1
x & -x //得到最右边的1
一般通过异或(^)和(清除最右边的1和得到最右边的1)来进行计算。
剑指 Offer II 004. 只出现一次的数字
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer>map=new HashMap<Integer, Integer>();
for(int num :nums){
// 当Map集合中有这个key时,就使用这个key对应的value值,如果没有就使用默认值defaultValue
map.put(num,map.getOrDefault(num,0)+1);
}
int ans=0;
for(int num:nums){
if(map.get(num)==1) ans=num;
}
return ans;
}
}
class Solution {
public int singleNumber(int[] nums) {
//位运算
// 如果一个数字出现3次,它的二进制每一位也出现的3次。
// 如果把所有出现三次的数字的二进制的每一位都分别加起来,那么每一位都能被3整除
// 如果某一位不能被3整除,那么只出现一次的那个数字的该位置一定为1
int []a=new int[32];
for(int num:nums){
for(int i=0;i<32;i++){
a[i]+=((num>>i)&1)==1?1:0;
}
}
int ans=0;
for(int i=0;i<32;i++)
{
a[i]%=3;
if(a[i]==1){
ans+=(a[i]<<i);
}
}
return ans;
}
}
剑指 Offer 65. 不用加减乘除做加法
class Solution {
public int add(int a, int b) {
while(b!=0){
int c=(a&b)<<1;
a^=b;
b=c;
}
return a;
}
}
剑指 Offer 56 - I. 数组中数字出现的次数
class Solution {
public int[] singleNumbers(int[] nums) {
int res=0;
for(int num:nums){
res^=num;
}
int ans=1;
int x=0,y=0;
while((res&ans)==0){
ans<<=1;
}
for(int num:nums){
if((ans&num)==0) x^=num;
else y^=num;
}
return new int[]{x,y};
}
}