338. Counting Bit DP看我很简单的!

题目:戳我

这题挺有意思的。本来看到这个直接暴力的。但他下面给了些限制,就促使我去重新思考这个问题,寻求更高效的方法
_
其实他不说我也想不到去用_builtin_popcount这个东西,我都没听过 捂脸
来,思考一下。先用笔模拟1-8,没啥规律。再想想看,题目要求是O(n)的欸,那意味着只能遍历一次,那意味着他肯定和前面的有不为人知的关系呀!然后在模拟一下加的过程,这时明白了!
过程: 求第i个数的1个个数,i = i-1 +1对吧。也就是说第i个数是第i-1个数的最低位(二进制)加了1.OK,nice!那么第i-1个数的最低位只有两种情况,分情况讨论呗。
注:最低位用low表示
1.当low = 0,第i个数比第i-1个数多1,
即:dp[i]=dp[i-1]+1
2.当low = 1,想想看,此时再加1,low肯定为0,也就相当于把第i-1个数的二进制形式向右移了一位,再把此时的low加1(这里1是进位勒). ,那么,转念一想,哇塞,就是第((i-1)>>1)+1位的个数吧!!!好好想一想,动笔写一写,例如3是011,加1最低位是0不管他,向右移一位,变成01,再把进位加上 就是10,也就是2!Bingo!即:dp[i] = dp[(i>>1)+1]
可以,思路有了,代码还会远吗
上代码:

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int>dp(num+1,0);
        for(int i = 1;i<=num;++i)
           dp[i] = ((i-1)&1) ? dp[((i-1)>>1)+1] : dp[i-1]+1;
        return dp;
    }
};

有一些话,没处说,这两天也一直在想,本人大四了,面临考研了,然而最近却总是患得患失,一方面想着错过秋招怎么办啊,先拿个offer兜底吧,一方面又想着破釜沉舟,考研一条路走到底。最近脑袋里这两个想法一直在斗争,这也是为什么我深夜还在写leetcode。是恐慌,是期待,归根结底都是菜。如果有心人看到,能给些建议,感激不尽。可以私信我,或者发我qq:1045398835@qq.com 也希望你加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值