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
相關文章
相關標籤/搜索