【面试题15 二进制中1的个数】
难度: 简单
考察: 位运算
请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
Leetcode题目对应位置: 面试题15:二进制中1的个数
判断所给二进制数最右边第一位是否为 1,若是 1 则计数器加 1;接着将二进制数整体右移一位,此时再判断右边第一位是否为 1,一直循环到二进制数变为 0 为止。
问题转化为: 移位操作 & 判断二进制数最右边是否为 1
判断一个二进制数最右边是否为 1,可以用 1 与其做“与运算”。由于 1 除了最右边位为 1,其余位都为 0,所以与任意二进制数相与,若结果为 1,说明二进制数最右边位是 1,否则就是 0。
时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n), l o g 2 n log_2n log2n 表示所给数 n 最高位 1 的所在位数
空间复杂度: O ( 1 ) O(1) O(1)
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0
while n:
count += n & 1
n >>= 1
return count
首先将 n 与辅助数字 1 做“与运算”,判断最右边位是否为 1;然后将辅助数字 1 左移一位,得到 10(十进制的 2),再和 n 做“与运算”判断。像这样不断将辅助数字左移,就能判断 n 的对应位置是否为 1。循环终止条件是移动后的辅助操作数大于 n。
时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n), l o g 2 n log_2n log2n 表示所给数 n 最高位 1 的所在位数
空间复杂度: O ( 1 ) O(1) O(1)
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0
m = 1
while m <= n:
if n & m: count += 1
m = m << 1
return count
将一个二进制数减去 1 的结果与原二进制数做“与运算”,会把该整数最右边的 1 变成 0,而其余位都不变。那么一个二进制数中有多少个 1,就进行多少次这样的操作,便能够统计出有多少个 1 了。这样做的好处是,二进制数中有几个 1 就循环几次,效率最高。
时间复杂度: O(m),m 为所给数字中 1 的个数,最坏情况下,m = n(数字位数)
空间复杂度: O(1)
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0
while n:
count += 1
n &= (n - 1)
return count
需要注意的点:
参考资料:
[1] 剑指 offer 第二版
[2] LeetCode 刷题 面试题15:二进制中1的个数