关于位运算的使用 可以从 C语言就开始使用
这里简单介绍常见的位运算
目录
[对数字第 x 位的常用操作](#对数字第 x 位的常用操作)
- & 按位与:同 1 得 1;判奇偶、清零位
- | 按位或:有 1 得 1;置 1 特定位
- ^ 异或:不同得 1;交换数字、翻转位
- ~ 取反 :0、1 互换;
~x = -x-1 - << 左移:左移 n 位,低位补 0 ≈ ×2ⁿ
- >> 右移
- 算术右移 (有符号):补符号位 ≈ ÷2ⁿ
- 逻辑右移 (无符号):高位补 0
对数字第 x 位的常用操作
- 查询第 x 位是 0 / 1 :
(n >> x) & 1 - 把第 x 位设置为 1 :
n |= (1 << x) - 把第 x 位设置为 0 :
n &= ~(1 << x)
异或三大核心性质
a ^ 0 = aa ^ a = 0(抵消)a ^ b ^ c = a ^ (b ^ c)(交换律、结合律)
提取二进制最右侧的 1 :n & -n
清除二进制最右侧的 1 : n & (n - 1)
判断字符是否唯一

java
public boolean isUnique(String astr) {
if(astr.length() > 26)
return false;
//
int bitMap = 0;
for(int i = 0; i <astr.length();i++){
int x = astr.charAt(i) - 'a';
if(((bitMap >> x) & 1) == 1)
return false;
//加入到位图中
bitMap |= (1 << x);
}
return true;
}
丢失的数字

java
public int missingNumber(int[] nums) {
int ret = 0;
for(int num : nums)
ret^= num;
for(int i = 0; i <= nums.length; i++ )
ret ^= i;
return ret;
}
两整数求和

java
public int getSum(int a, int b) {
while(b != 0){
int x = a ^ b;
int carry = (a & b) << 1;
a = x;
b = carry;
}
return a;
}
丢失的两个数字

java
public int[] missingTwo(int[] nums) {
//1.丢失的数字
int tmp = 0;
for(int x : nums){
tmp ^= x;//将全部数据异或
}
for(int i = 0; i<= nums.length + 2; i++){
tmp^= i;
}
//2. 找出 a,b 不同的比特位
int diiff = 0;
while(true) {
if(((tmp >> diiff) & 1) == 1 )
break;
else
diiff++;
}
//3.只消失的一个数字|||
int[] ret = new int[2];
for(int x : nums){
if(((x >> diiff) & 1 ) == 1)
ret[0] ^= x;
else
ret[1] ^= x;
}
for(int i = 0; i <= nums.length + 2;i++){
if(((i >> diiff) & 1) == 1 )
ret[0] ^= i;
else
ret[1] ^= i;
}
return ret;
}
只出现一次的数字||

java
public int singleNumber(int[] nums) {
int ret = 0;
for(int i = 0; i < 32; i++){
int sum = 0;
for( int x : nums)
if((( x >> i )&1) == 1)
sum++;
sum %= 3;
if(sum == 1)
ret |= (1 << i);
}
return ret;
}