1 位移的妙用
位1的个数
LeetCode191 Easy

最关键的就是 n = n & (n - 1) 这句话,首先他的作用是 是将整数 n 的二进制表示中的最后一个 1 变为 0。这个操作可以用来统计一个整数中的二进制表示中有多少个 1(也被称为 "位1的个数" 问题)


public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
// 汉明重量 hammingWeight
int count = 0;
while (n != 0) {
// 这个操作会把 n 机器数的最后一个 1 给去掉
n = n & (n - 1);
count++;
}
return count;
}
}
还有一种方式:利用 & 运算的性质 + for 循环进行遍历
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
for (int i = 0; i < 32; i++) {
count += (n >> i) & 1;
}
return count;
}
}
比特位计数
LeetCode338 Easy

就是两个 for 循环,进行遍历,主要的还是上一题的思路
class Solution {
public int[] countBits(int n) {
int[] bits = new int[n + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j < 32; j++) {
bits[i] += (i >> j) & 1;
}
}
return bits;
}
}
还有其他思路,就是是使用 n = n & (n - 1);
class Solution {
public int[] countBits(int num) {
int[] bits = new int[num + 1];
for (int i = 0; i <= num; i++) {
bits[i] = countOnes(i);
}
return bits;
}
public int countOnes(int x) {
int ones = 0;
while (x > 0) {
x &= (x - 1);
ones++;
}
return ones;
}
}
颠倒无符号整数
由于是无符号整数所以相当于简单
LeetCode190 Easy

由于可以向前移动,所以思路也不是非常复杂,而且要用 & 运算这样可以复制反转前对应的值
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
int reversInt = 0, power = 31;
while (n != 0) {
reversInt += (n & 1) << power;
// n 进行无符号右移动
n >>>= 1;
power--;
}
return reversInt;
}
}
位实现加减乘除专题
位运算实现加法
LeetCode371 Medium

class Solution {
public int getSum(int a, int b) {
while (b != 0) {
// 需要进的位数
// 如果是两个 1 那么就要进位,所以需要判断是不是两个 1 所以需要进行 & 运算,而且还需要向前移动一位
int sign = (a & b) << 1;
// 进行异或运算,相同为 0 不同为 1 ,非常符合加法运算,就是 如果是两个 1 那么这个位上应该是 0 ,如果是两个 0 的话那么这个位上应该也是 0 ,其他情况下就是 1
a = a ^ b;
b = sign;
}
return a;
}
}
递归乘法
LeetCode 面试题 08.05. 递归乘法Medium

class Solution {
public int multiply(int A, int B) {
int min = Math.min(A, B);
int max = Math.max(A, B);
int ans = 0;
// 循环,分别将 min 不断右移(相当于除以2),同时将 max 不断翻倍
for (int i = 0; min != 0; i++) {
// 当 min 的二进制表示末位为 1 时,表示 min 是奇数,这时将 max 加到 ans 上
// 当 min 是偶数的时候可以这样想:3 * 4 = (1 + 2)* 4 所以 max 就可以直接加到 ans 里面,因为有一个 1 和 max 相乘结果还是 1 的
if ((min & 1) == 1) {
ans += max;
}
// min 右移一位,相当于 min 除以 2
min >>= 1;
// max 翻倍,相当于 max 乘以 2
max += max;
}
return ans;
}
}