GitHub链接:algorithmzuo (左程云) · GitHub
第一部分:
方法一:
package class031;
// Brian Kernighan算法
// 提取出二进制里最右侧的1
// 判断一个整数是不是2的幂
// 测试链接 : https://leetcode.cn/problems/power-of-two/
public class Code01_PowerOfTwo {
public static boolean isPowerOfTwo(int n) {
return n > 0 && n == (n & -n);
}
}
方法二:
return n>0 && n&(n-1)==0
第二部分:
根据范围设计算法
package class031;
// 判断一个整数是不是3的幂
// 测试链接 : https://leetcode.cn/problems/power-of-three/
public class Code02_PowerOfThree {
// 如果一个数字是3的某次幂,那么这个数一定只含有3这个质数因子
// 1162261467是int型范围内,最大的3的幂,它是3的19次方
// 这个1162261467只含有3这个质数因子,如果n也是只含有3这个质数因子,那么
// 1162261467 % n == 0
// 反之如果1162261467 % n != 0 说明n一定含有其他因子
public static boolean isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
}
第三部分:
把最左边1的后面全刷成1,然后加一
package class031;
// 已知n是非负数
// 返回大于等于n的最小的2某次方
// 如果int范围内不存在这样的数,返回整数最小值
public class Code03_Near2power {
public static final int near2power(int n) {
if (n <= 0) {
return 1;
}
n--;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return n + 1;
}
public static void main(String[] args) {
int number = 100;
System.out.println(near2power(number));
}
}
第四部分:
每次消掉最右边的一
可能性一:
right大于left,那么right-1一定存在,并且right-1遇上right一定会把最右边的一给消掉
因为与运算中,只要有一个是0,就都是0了
可能性二:
right小于等于left
package class031;
// 给你两个整数 left 和 right ,表示区间 [left, right]
// 返回此区间内所有数字 & 的结果
// 包含 left 、right 端点
// 测试链接 : https://leetcode.cn/problems/bitwise-and-of-numbers-range/
public class Code04_LeftToRightAnd {
public static int rangeBitwiseAnd(int left, int right) {
while (left < right) {
right -= right & -right;
}
return right;
}
}
第五部分:
分治:部分逆序一直到整体逆序,利用递归来反向思考挺好
package class031;
// 逆序二进制的状态
// 测试链接 : https://leetcode.cn/problems/reverse-bits/
public class Code05_ReverseBits {
// 逆序二进制的状态
// 是不是看着头皮发麻啊?代码看着很魔幻吧?别慌
public static int reverseBits(int n) {
n = ((n & 0xaaaaaaaa) >>> 1) | ((n & 0x55555555) << 1);
n = ((n & 0xcccccccc) >>> 2) | ((n & 0x33333333) << 2);
n = ((n & 0xf0f0f0f0) >>> 4) | ((n & 0x0f0f0f0f) << 4);
n = ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8);
n = (n >>> 16) | (n << 16);
return n;
}
}
第六部分:
利用某一个区间来表示这个区间所含有的一的数量,然后局部推导到整体,有点像递归呀
package class031;
// 返回n的二进制中有几个1
// 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
// 给你两个整数 x 和 y,计算并返回它们之间的汉明距离
// 测试链接 : https://leetcode.cn/problems/hamming-distance/
public class Code06_CountOnesBinarySystem {
public static int hammingDistance(int x, int y) {
return cntOnes(x ^ y);
}
// 返回n的二进制中有几个1
// 这个实现脑洞太大了
public static int cntOnes(int n) {
n = (n & 0x55555555) + ((n >>> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >>> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >>> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >>> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >>> 16) & 0x0000ffff);
return n;
}
}
5726



被折叠的 条评论
为什么被折叠?



