ID:338.比特位计数

51 阅读1分钟

题目

给你一个整数 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;
};