LeetCode每日一题题解(2021-3-3-Q338)

1.题目描述

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:

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

示例 2:

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

2.题目分析

问题要求返回0~num二进制数中1的个数,先写几个二进制数看看规律

十进制数二进制数1的个数
000000
100011
200101
300112
401001
501012
601102
701113

观察上表,可以看出以下几个结论:

  • 2的整数次幂1的个数是1(首位是1,后面全0)

  • 有递推的关系(以7为例):
    观察1、3、7的二进制表示

    十进制数二进制数1的个数
    100011
    300112
    701113

    0111就是0011多一个高位,同样的0011是0001多一个高位
    f ( x ) 表 示 x 的 二 进 制 表 示 中 1 的 个 数 f ( 7 ) = f ( 3 ) + 1 f ( 3 ) = f ( 1 ) + 1 f(x)表示x的二进制表示中1的个数\\ f(7)=f(3)+1\\ f(3)=f(1)+1\\ f(x)x1f(7)=f(3)+1f(3)=f(1)+1

按照这个思路很自然想到递归求个数,反过来就是动态规划了。套用上面的规律可以得到:
f ( x ) = f ( x − y ) + 1 y 是 小 于 x 的 最 大 的 2 的 幂 次 方 在 上 例 中 7 对 应 4 , 3 对 应 1 f(x)=f(x-y)+1\\y是小于x的最大的2的幂次方\\在上例中7对应4,3对应1 f(x)=f(xy)+1yx27431
得到递推方程后即可写出代码:

class Solution {
    public int[] countBits(int num) {
        int[] binNum = new int[num+1];
        binNum[0] = 0;
        if(num == 0){
            return binNum;
        }
        binNum[1] = 1;
        int temp1 = 2;
        int temp2 = 2 * temp1;
        for (int i = 2; i <= num; i++) {
            if(i == temp2){
                binNum[i] = 1;
                temp1 = temp2;
                temp2 *= 2;
            }
            binNum[i] = binNum[i-temp1] + 1;
        }
        return binNum;
    }
}

这里用了temp中间变量来寻找2的整数次幂,在官方题解里找到一个简单方法(注意到这种数最高位1低位全0):

y&(y−1)=0 //y是2的整数次幂

2021-3-3打卡成功!继续加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值