338.Counting Bits---位运算---《剑指offer》32

题目连接:https://leetcode.com/problems/counting-bits/description/数组

题目大意:求解从0到num的全部数的二进制表示中全部1的个数。ide

法一:暴力解,两个for循环,分别求解每个二进制表示,而后计数其中1的个数。代码以下(耗时9ms):优化

 1     public int[] countBits(int num) {
 2         int[] res = new int[num+1];
 3         for(int i = 0; i <= num; i++) {
 4             res[i] = bit(i);
 5         }
 6         return res;
 7     }
 8     public static int bit(int num) {//转换为二进制计数1的个数
 9         int cnt = 0;
10         while(num != 0) {
11             cnt += num % 2;
12             num /= 2;
13         }
14         return cnt;
15     }
View Code

法二:在法一的基础上,优化了内层循环,利用记忆搜索的思想,由于已经用res数组存下了i以前数据的1的个数,而当i/2以后获得的数据,必定是以前已经计算过的数据,这样就能够直接拿过来用,而不用再次计算。好比要计算5时,只须要算出5%2获得的数值,而后就要对5进行/2运算了,而5/2=2,在前面已经存储过res[2]的数值了,因此就获得res[5]=5%2+res[5/2]。代码以下(耗时3ms):spa

1     public int[] countBits(int num) {
2         int[] res = new int[num+1];
3         res[0] = 0;
4         for(int i = 1; i <= num; i++) {
5             int tmp = i;
6             res[i] = (tmp % 2) + res[tmp / 2];
7         }
8         return res;
9     }
View Code

 法三:在法二的基础上,用位运算的办法来作取余和除2运算。的确快了点。代码以下(耗时2ms):3d

1     public int[] countBits(int num) {
2         int[] res = new int[num + 1];
3         res[0] = 0;
4         for(int i = 1; i <= num; i++) {
5             res[i] = (i & 1) + res[i >> 1];
6         }
7         return res;
8     }
View Code
相关文章
相关标签/搜索