比特位计数的基本实现与优化

一.算法题干

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

二.样例

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

三.解题思路

我一开始想到的是最正统的解法:遍历[0,num]的所有整数,然后对每个整数都不断进行“模2+除以2”的操作,统计这当中模2后得到1的数量(其实也就是转化为二进制后1的个数),最后输出各个小结果组成的vector。

四.实现代码

vector<int> countBits(int n) {
	vector<int> resv;
	for(int i=0;i<=n;++i)
	{
		int t=i,res=0;
		while(t)
		{
			if(t%2) ++res;
			t/=2;
		}
		resv.push_back(res);
	}
}

五.对比分析

通过观察别人写的代码我发现我针对该问题的实现方式还不够巧妙。别人的代码实现如下图所示。

vector<int> countBits(int num) {
	vector<int> result(num+1);
	result[0]=0;
	for(int i=0;i<=num;++i)
	{
		if(i%2==1) result[i]=result[i-1]+1;
		else result[i]=result[i/2];
	}

	return result;
}

该解题方法的设计主要是考虑到了奇偶数交替变化中隐藏的规律,运用了DP(动态规划)的思想。动态规划的基本原则就是根据之前已经得到的结果,结合公式推演得到当前的结果,其特点是当前结果依赖于子问题的结果。动态规划的核心有两点:找到递推公式、确定起始状态。在本题中,递推公式的确定依赖于针对整数奇偶性的分类。具体的分类规则如下:针对奇数,在二进制表示中,奇数一定比其前面那个偶数多一个1,因为多的就是最低位的1;针对偶数,在二进制表示中,偶数中1的个数一定和除以2后得到的那个数一样多(因为最低位是0,除以2 就是右移一位,也就是把那个0 抹掉而已,所以1 的个数是不变的)。初始状态,也就是整个递推的起点,即0只有0个1。由此可以得到整个算法的实现方法。

六.题目来源

338. 比特位计数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值