解题思路一:位运算
计算(n & 1) == 1
,如果满足条件,那么就让返回的结果res++
;然后令n
无符号右移一位,直至n == 0
这里面涉及到的位运算符有:
&
,即:按位与- 无符号右移
>>>
,无符号右移num >>> n
的意思是,无论num
是正数还是负数,将其右移n
位后,高位补0
代码
Java
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while(n != 0){
res += n & 1;
n = n >>> 1;
}
return res;
}
}
复杂度分析
- 时间复杂度:O(N)
其中,N 为二进制数的长度,我们需要对二进制数的每一位和 1 做与运算并让二进制数无符号右移直至二进制数为 0;所以该算法的时间复杂度为:O(N)
_
- 空间复杂度:O(1)
我们只使用了有限的几个变量,所以该算法的额外空间复杂度为:_O(1)
_
解题思路二:巧用位运算n & (n - 1)
n & (n - 1)
是位运算中非常非常重要的一种技巧,它是将二进制数n
最右边的1
变成0
的操作
示例:n = 10101000
n = 10101000
n - 1 = 10100111
n & (n - 1) = 10100000 // 将二进制数n最右边的那个1变成了0,其余不变
有了这个技巧,我们就可以优化我们的算法,将算法的时间复杂度提升到O(M)
其中M
为二进制数n
中1
的个数
代码
Java
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while(n != 0){
n = n & (n - 1);
res++;
}
return res;
}
}
复杂度分析
- 时间复杂度:O(M)
_M 为二进制数 N 中 1 的个数,相比于第一种算法,该算法的时间复杂度要优于前者。
- 空间复杂度:O(1)
算法中只使用到了有限的几个变量,所以额外空间复杂度为:_O(1)