leetcode 338 Counting Bits

来源:互联网 发布:新开淘宝店卖什么好 编辑:程序博客网 时间:2024/06/10 10:04

leetcode 338 Counting Bits

题目大意:

给定一个非负整数num,要求你计算 0<=i<=num范围中,每个i的二进制表示中,有几个1;

例如,给定num=5,那么在0<=i<=num的范围汇中的数为{0,1,2,3,4,5},那么他们对应的二进制表示中,各自含有的1的个数为{0,1,1,2,1,2}。

两种解题思路:

第一种解题思路,写出一些数,然后统计规律:

根据每个数二进制及移位原理可以发现:

(1)当此数为偶数时(0除外,单独讨论),该数的2倍,其含有的1的个数与其相同,这个其实不难理解,2倍,即把原来的那个数,向左移动1位,右边补0,所以含1的个数相同,因此,f(n)=f(n/2);

(2)当该数为奇数时,那么该数的上一个数,即n-1,一定为偶数,由于,偶数的最低位一定为0,所以当把该偶数的最低位变为1后,(即+1),该偶数就变为了奇数,所以有f(n)=f(n-1)+1;

(3)当n=0时,其二级制中包含的1的个数为0;

所以根据以上分类讨论,可以得到如下规律:

(1)f(n)=f(n/2),if n为偶数;

(2)f(n)=f(n-1)+1,if n为奇数;

(3)f(n)=0,if n为0


AC代码如下,仅供参考。

class Solution {public:vector<int> countBits(int num) {vector<int>dp(num + 1, 0);for (int i = 1; i <= num; i++) {if (i%2 == 0) dp[i] = dp[i / 2];else dp[i] = 1 + dp[i - 1];}return dp;}};

第二种解题思路,根据位操作来解题:
假设有一个数a,将其与a-1作位与运算,即 b = a&(a-1),则 b 的二进制表示中的‘1’ 的数目恰好比 a 的二进制表示中的‘1 ’的数目 少 1个(也就是说,把一个整数减去1,再和原整数做与运算,会把该原整数的最右边的1变成0,这种思想还可以用于统计一个数的二级制表示中有多少个‘1’)。举例来说,假设 a 二进制表示为 1100,那么 a - 1  的二进制表示为 1011 , a & b = 1100 & 1011 = 1000 = b,所以 a  的二进制中‘1’的数目就是 b 的二进制中‘1’的数目 + 1。基于上述思路,可写出如下AC代码。

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


0 0