【LeetCode】338. 比特位计数

这篇博客介绍了如何利用位运算和动态规划解决计算整数二进制表示中1的个数问题。作者解析了一个巧妙的算法,对于每个数i,如果是奇数则结果比前一个数多1,偶数则等于自身一半的1的个数。关键操作i&(i-1)用于消除二进制表示的最后一个1,从而求得1的个数。此题需要一定的位运算经验和对二进制的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态规划题,但是很有技巧性,针对于位运算和二进制有点说法。

338. 比特位计数

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

class Solution {
public:
    vector<int> countBits(int n) {
        vector<int>ans(n+1);
        ans[0]=0;
        for(int i=1;i<=n;++i){
            ans[i]=ans[i>>1]+(i&1);
        }
        return ans;
    }
};

首先说这是一个统计二进制数的1的个数的题,通过别人对这道题规律的解答来看,就是说:

如果是奇数,结果就是它前一个数1的个数+1

如果是偶数,结果就是它自身一半的数的1的个数

总结就是,都与自身一半看齐。

同时为了区分奇偶性,引入了i&1这种操作。

这个操作乍一看不知道是干啥的,仔细研究发现,如果是奇数i,那二进制结果必然是1,结果也就是1,如果是偶数,结尾是0,结果就会是0。

同时,采用左移右移的操作进行效率上的简化。

得到:ans[i]=ans[i>>1]+(i&1)这种“高端”操作,要我自己想肯定想不出来...

也就是说,如果是奇数,就会+1,不是奇数就不加。

这类题我感觉就要靠经验了,因为你考试时候现想还是有点费劲的。


关于位运算,有操作x&(x-1)

x&(x-1)能消去二进制x的最后一个1,也就是说,反复对一个数进行循环的这种操作,得出的结果,就是该数字二进制,1的个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值