一、位运算符
二、常见的位运算问题
2.1 异或特点n^n=0 n^0=n
- 数组中每个数字都出现了两次,只有一个出现了一次,找到出现一次的数字(leetcode 136)
- 根据异或特点
n^n=0 n^0=n
,异或到最后只剩下0^n
public static int singleNumber(int[] nums) {
int num = 0;
for (int i = 0; i < nums.length; i++) {
num = num ^ nums[i];
}
return num;
}
2.2 求汉明距离
- 整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目,求两个整数x,y的汉明距离(leetcode 461)
- 异或获取不同位置,再通过位移
num & 1
判断1的数量
public int hammingDistance(int x, int y) {
int z = x ^ y;// 取异或 不同位置为1,如 1001 ^ 0110 = 1111
int sum = 0;
while (z!=0){
sum += z & 1;// 如果z最低位为1,结果为1 否则为0 如1111&0001=0001
z = z>>1;// z 向右移一位
}
return sum;
}
2.3 n&(n-1) 后的1比n少一个
- 计算二进制数字中1的个数(leetcode 191)
- n&(n-1) 后的1比n少一个
- 6(110)&5(101) = 4(100) 4(100)&3(011)=0(000)
public int NumberOf1(int n) {
int count = 0;
while (n != 0 ) {
count++;
n = (n - 1) & n// 将n的二进制中的1减少一个
}
return count;
}
2.4 位操作判断奇偶数
- 只要根据数的最后一位是 0 还是 1 来决定即可,为 0 就是偶数,为 1 就是奇数。
if(0 == (a & 1)) {
//偶数
}
2.5 位操作交换符号
- 交换符号将正数变成负数,负数变成正数
int reversal(int a) {
return ~a + 1;
}
2.6 乘2除2
- 左移一次等于乘2,右移一次等于除2(不要溢出)
三、源码中的位运算
3.1 hashMap中的位运算
Map (三) HashMap 如何利用 hash 计算存储位置
Map (四) HashMap 已故事的角度理解 resize()