2021/03/03 每日一题 位计数

LeetCode位计数,中等难度,记录下解题思路

输入一个数num,需要求[0,num]区间内所有数对应的二进制数中1的数量

计算一个数的二进制中1的个数,可以直接将一个数转换为二进制例如5 = 2^2 + 2^0 = 101
也可以拆分为5 = 4 + 1
其中4直接是2^2对应的就是100,是除了第一位以外所有的数均为0的情况,之后加上2^0001,那么就可以得到101
那么运用动态规划的思路:
1 = 2^0
2 = 2^1
3 = 2^1 + 2^0
4 = 2^2
5 = 2^2 + 2^0
6 = 2^2 + 2^1
7 =2^2 + 2^1 + 2^0
如果一个数是2的整次幂,那么这个数二进制对应1的个数为1
如果一个数不是2的整次幂,那么这个数可以拆分为res[i] = res[i -最近一个整数次幂的数] + 1res数组是对应数字二进制中1的个数
例如:
res[5] = res[5-4] + 1 = 2
res[6] = res[6-4] + 1 = res[2] + 1 = 2
res[7] = res[7-4] + 1 = res[3] + 1 = res[3-2] + 1 + 1 = res[1] + 1 + 1 = 3

这样推导下来就能很清楚的看到动态规划的公式,所以最后实现的过程如下:

  1. 遍历[0,num]中间所有数,并且已知res[0] = 0
  2. 如果这个数是2的整数次幂就保存下来,记为high,并且这个数的count = 1
    判断整数次幂用i & (i - 1)) === 0
    例如4 = 1003 = 011来做与运算结果就是0
    5 = 1014 = 100做与运算结果为100不为0
  3. 如果这个数不是2的整数次幂,就查用保存的high和当前数相减res[i] = res[i - high] + 1这个公式来计算结果
var countBits = function(num) {
   // 创建结果数组
    const res= new Array(num + 1).fill(0);
   // 定义当前最高位为0
    let highBit = 0;
   // 从1开始遍历整个数
    for (let i = 1; i <= num; i++) {
        // 如果是2的整数次幂
        if ((i & (i - 1)) === 0) {
            // 保存当前数
            high = i;
            // 将当前数对应的结果设为1
            res[i] = 1
            // 跳出本次循环
            continue
        }
        // 计算结果
        res[i] = res[i - high] + 1;
    }
    return res;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 进制基本概念 什么是进制?进制是一种计数的方式,数值的表示形式 常见的进制十进制、二进制、八进制、十六进制 进制书...
    低头看云阅读 944评论 0 1
  • 我自己琢磨着,数学抽象概念最重要。如果概念理解清楚了,数学的抽象思维就进了一步。概念清楚了很多内容就可以穿起来了,...
    尘尘肥妈阅读 1,397评论 0 1
  • ### 内置函数 > 内置函数就是在系统安装完python解释器时,由python解释器给提供好的函数 ### [...
    lmonkey_01阅读 106评论 0 0
  • 难度中等题目描述: 给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数...
    hqwer阅读 127评论 0 0
  • 进制基本概念 什么是进制?进制是一种计数的方式,数值的表示形式 常见的进制十进制、二进制、八进制、十六进制 进制书...
    Cc_5691阅读 4,070评论 0 3

友情链接更多精彩内容