191. 位1的个数
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-1-bits
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。
提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。
分析:起初思路为循环取余,除二,进行计算即可
根据提示发现忽略了负数情况,
负数情况进行非运算,再用32减去取非后1的位数即可
个人答案:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int sum=0;
int flag=0; //负数判断
if(n<0){
n=~n;
flag=1;
}
while(n>0){
if(n%2==1){
sum++;
}
n/=2;
}
if(flag==1){
sum=32-sum;
}
return sum;
}
}
官方解法:
方法1:
算法
这个方法比较直接。我们遍历数字的 32 位。如果某一位是 11 ,将计数器加一。
我们使用 位掩码 来检查数字的第 i^{th}
位。一开始,掩码 m=1因为 11 的二进制表示是
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0001
显然,任何数字跟掩码 11 进行逻辑与运算,都可以让我们获得这个数字的最低位。检查下一位时,我们将掩码左移一位。
0000 0000 0000 0000 0000 0000 0000 0010
0000 0000 0000 0000 0000 0000 0000 0010
并重复此过程。
public int hammingWeight(int n) {
int bits = 0;
int mask = 1;
for (int i = 0; i < 32; i++) {
if ((n & mask) != 0) {
bits++;
}
mask <<= 1;
}
return bits;
}
方法 2:位操作的小技巧
算法
我们可以把前面的算法进行优化。我们不再检查数字的每一个位,而是不断把数字最后一个 1 反转,并把答案加一。当数字变成 0 的时候偶,我们就知道它没有 1 的位了,此时返回答案。
这里关键的想法是对于任意数字 n ,将 n 和 n - 1做与运算,会把最后一个 1 的位变成 0 。为什么?考虑 n 和 n - 1 的二进制表示。
图片 将 n 和 n-1做与运算会将最低位的 1 变成 0
在二进制表示中,数字 n 中最低位的 1 总是对应 n - 1 中的 0 。因此,将 n 和 n - 1 与运算总是能把 n 中最低位的 1 变成 0 ,并保持其他位不变。
使用这个小技巧,代码变得非常简单。
public int hammingWeight(int n) {
int sum = 0;
while (n != 0) {
sum++;
n &= (n - 1);
}
return sum;
}
来源:力扣(LeetCode)