[力扣每日一题]191.位1的个数
题目详情
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为’1’的个数(也被称为汉明重量)
提示
输入必须是长度为32的二进制串
进阶
如果多次调用这个函数,如何优化你的算法?
1.暴力解法
public class LCode191 {
public static void main(String[] args) {
int num = 00000000000000000000000010000000;
System.out.println(hammingWeight(num));
}
public static int hammingWeight(int num) {
int result = 0;
for (int i = 0; i < 32; i++) {
if ((num & (1 << i)) != 0) {
result++;
}
}
return result;
}
}
思路:循环检查。当检查第i位时,我们可以让n与2的i次方进行与(且)运算,当且仅当n的第i位为1时,运算结果不为0。
2.位运算优化
观察n&(n-1),其运算结果恰为把n的二进制位中最低位的1变为0之后的结果。
如:6&(6-1)=4,6=110(二进制),4=100(二进制),运算结果4即为把6的二进制位中的最低位的1变为0之后的结果。
这样我们可以利用这个位运算的性质加速我们的检查过程。在代码中,我们不断让当前的n和n-1做与运算,直到n变为0为止。
因为每次运算会使得n的最低位的1被翻转,因此运算次数就等于n的二进制位中1的个数。
public class LCode191 {
public static void main(String[] args) {
int num = 00000000000000000000000011110000;
System.out.println(hammingWeight(num));
}
public static int hammingWeight(int num) {
int result = 0;
while (num != 0) {
num = num & (num - 1);
result++;
}
return result;
}
}
[相关总结]二进制、位运算
-
1<<n就等价于2的n次方
-
& 与(AND)运算符,对两个整型操作数中对应位执行布尔代数,两个位都为1时输出1,否则0
| 或(OR)运算符,对两个整型操作数中对应位执行布尔代数,两个位中只要有一个为1就输出1,否则为0
^ 异或(XOR)运算符,对两个整型操作数中对应位执行布尔代数,两个位相等则为0,不相等则为1
~ 非(NOT)运算符,按位取反运算符翻转操作数的每一位,即0变成1,1变成0