题目
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
思路
找规律即可
var countBits = function(n) {
// 4: 0 1 1 2
// 8: 1 2 2 3
// 16: 1 2 2 3 2 3 3 4
// 32: 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5
// 64: 1 2 2 3 2 3 3 4 2 3 3 4 3 4 4 5 2 3 3 4 3 4 4 5 3 4 4 5 4 5 5 6
const res = [0, 1, 1, 2, 1, 2, 2, 3];
if(n < 8) return res.slice(0, n + 1);
// 2^p表示当前数字未超过的值
// _2p存储2^p的值
// _2p_2存储2^(p-2)的值
let p = 3, _2p = 0, _2p_2 = 0;
for(let i = 8; i <= n; i++) {
// 如果i等于2的乘方
if(i === 2 ** p) {
res.push(1); // 2的乘方的二进制字符串肯定只有一个1
p++; // 乘方数自增
_2p = 2 ** p;
_2p_2 = 2 ** (p - 2);
} else {
// 这里的表达式其实应该是 i - 2 ^ (p - 1) < 2 ^ (p - 2)
// 当前行的前半部分等于上一行,
// 后半部分等于上一行加1
if(i < 3 * _2p_2) {
res.push(res[i - _2p_2]);
} else {
res.push(res[i - _2p_2] + 1);
}
}
}
return res;
};