运算规则
& 按位与:二进制两个都为1则为1,否则为0
| 按位或:二进制两个中有一个为1则为1
^ 按位异或:两个二进制位值相同则为0,否则为1
~ 取反:一个二进制数按位取反,即将0变1,将1变0
<< 左移:将一个数的各二进制位全部左移N位,右补0
>>右移:将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0
使用技巧
1.消除二进制位中最后一个1
例子:消除x的最后一位1x = 1001x-1 = 1000& 为都为1则为1x&(x-1) = 1000
2.判断n是否为2的幂次方
时间复杂度O(1)
// 2的幂次方为 2的x次。所以二进制位中只有一个1存在。// 消除这个1的话就为0n&(n-1) == 0?
3.计算一个32位的二进制数有多少个1
// 依次进行最后一个1的消除。直到为0的时候结束循环// 循环多少次就证明有多少个1while(n>0){n = n&(n-1);count++;}
4.整数A转换为B需要改变多少个bit位
// 使用异或,相同则为0,不同则为1.所以使用异或之后计算1的个数就行
5.二进制进行子集的枚举
从0~2的(n-1)次方的组合。1所在的位置为一个组合
S = {1,2,3}N bit Combination0-> 000 {}1-> 001 {1}2-> 010 {2}3-> 011 {1,2}4-> 100 {3}5-> 101 {1,3}6-> 110 {2,3}7-> 111 {1,2,3}
6.a^b^b=a的使用
都相同为0,不同为1
数组中一个数出现了一次,其他的都出现了两次
// 出现两次的值满足a^a = 0int res = 0;for(Integer n:nums){res ^= n;}// 因为其他的两个的都互相消除了,所以剩下的值只有一个出现一次的return res;
数组中一个数出现了一次,其他的都出现了三次
