Skip to main content

比特位计数

Tips

题目类型: 位运算, 动态规划

相关题目:

题目

给定一个非负整数 n, 请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数, 并输出一个数组.

示例

输入: n = 5

输出: [0, 1, 1, 2, 1, 2]

解释:

0 --> 0

1 --> 1

2 --> 10

3 --> 11

4 --> 100

5 --> 101

题解

Tips

一般看到二进制统计 1 的个数先想到 Brian Kernighan 算法, 也就是 n & (n - 1). 关于使用 n & (n - 1), 这里不再赘述, 可访问位运算的一些技巧.

/**
* @param {number} n
* @return {number[]}
*/
var countBits = function (n) {
const bits = new Array(n).fill(0)

for (let i = 0; i <= n; i += 1) {
bits[i] = computeZero(i)
}

return bits
}

var computeZero = function (n) {
let count = 0

// 通过 n & (n - 1) 将 n 逐步抹零, 次数就是 1 的个数
while (n > 0) {
n = n & (n - 1)
count += 1
}

return count
}

复杂度分析

时间复杂度: O(nlogn), 一趟循环是 n, 计算从 0 到 n 的每个整数的一比特数的时间都不会超过 O(logn), 整体就是 O(nlogn).

空间复杂度: O(1), 除了返回的数组以外, 空间复杂度为常数.