题目描述
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
- 地址:https://leetcode-cn.com/problems/number-of-1-bits/
- 2021/03/22
法一:库函数
- 使用
bin()函数可以得到一个整数的二进制字符串 - 注意二进制以“0b”开头
- 时间复杂度 O(k)
空间复杂度 O(k) 其中 k 为 n 的二进制长度
class Solution(object):def hammingWeight(self, n):return bin(n).count("1")
法二:逐步右移统计 1 的个数
java注意逻辑右移和算数右移的差异
- 算术右移
>>:舍弃最低位,高位用符号位填补 - 逻辑右移
>>>:舍弃最低位,高位用 0 填补
- 算术右移
- n & 1 判断末尾是否为 1;然后把n右移,直到结束
- 时间复杂度:O(k)
空间复杂度:O(1)
class Solution(object):def hammingWeight(self, n):res = 0while n:res += n & 1n >>= 1return res
class Solution {public:int hammingWeight(uint32_t n) {int res = 0;while (n) {res += n & 1;n >>= 1;}return res;}};
法三:就涉及到 Brian Kernighan Algorithm
反正我是想不到,题解里面现学的(抄的),题解总有很多骚姿势
n &(n - 1),其运算结果恰为把 n 的二进制位中的最低位的 1 变为 0 之后的结果
class Solution {public:int hammingWeight(uint32_t n) {int res = 0;while (n) {n = n & (n - 1);res ++;}return res;}};
法四:还有一个终极解法(jdk源码)
时间复杂度:O(logk),k 为 int 的位数,固定为 32 位
- 空间复杂度:O(1)
- 巨人的肩膀:https://zhuanlan.zhihu.com/p/70950198
class Solution {public:int hammingWeight(uint32_t 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;}};
