【Leetcode】338. Bit位計數
阿新 • • 發佈:2018-05-13
一個 ems 進制數 tco rip 題目 res AS 都是
每次刷leetcode都有一種發現新大陸的感覺。
題目鏈接:https://leetcode-cn.com/problems/counting-bits/description/
給定一個非負整數 num。 對於範圍 0 ≤ i ≤ num 中的每個數字 i ,計算其二進制數中的1的數目並將它們作為數組返回。
示例:
比如給定num = 5
,應該返回[0,1,1,2,1,2]
.進階:
- 給出時間復雜度為O(n * sizeof(integer)) 的解答非常容易。 但是你可以在線性時間O(n)內用一次遍歷做到嗎?
- 要求算法的空間復雜度為O(n)。
- 你能進一步完善解法嗎? 在c ++或任何其他語言中不使用任何內置函數(如c++裏的 __builtin_popcount)來執行此操作。
0 0000 0 ------------- 1 0001 1 ------------- 2 0010 1 3 0011 2 ------------- 4 0100 1 5 0101 2 6 0110 2 7 0111 3 ------------- 8 1000 1 9 1001 2 10 1010 2 11 1011 3 12 1100 2 13 1101 3 14 1110 3 15 1111 4
找規律,以分割線為界限。比如4-7。4,5和2,3相同,但是6,7卻是2,3 加 1. 而8-15也符合類似的規則。可以用這個規律寫下代碼。
大神解法:
1 public int[] countBits(int num) { 2 int[] f = new int[num + 1]; 3 for (int i=1; i<=num; i++) 4 f[i] = f[i >> 1] + (i & 1); 5 return f; 6 }
下面這種方法就更加巧妙了,巧妙的利用了i&(i - 1), 這個本來是用來判斷一個數是否是2的指數的快捷方法,比如8,二進制位1000, 那麽8&(8-1)為0,只要為0就是2的指數, 那麽我們現在來看一下0到15的數字和其對應的i&(i - 1)值:
i bin ‘1‘ i&(i-1)
0 0000 0
-----------------------
1 0001 1 0000
-----------------------
2 0010 1 0000
3 0011 2 0010
-----------------------
4 0100 1 0000
5 0101 2 0100
6 0110 2 0100
7 0111 3 0110
-----------------------
8 1000 1 0000
9 1001 2 1000
10 1010 2 1000
11 1011 3 1010
12 1100 2 1000
13 1101 3 1100
14 1110 3 1100
15 1111 4 1110
我們可以發現每個i值都是i&(i-1)對應的值加1,這樣我們就可以寫出代碼如下:
1 class Solution { 2 public: 3 vector<int> countBits(int num) { 4 vector<int> res(num + 1, 0); 5 for (int i = 1; i <= num; ++i) { 6 res[i] = res[i & (i - 1)] + 1; 7 } 8 return res; 9 } 10 };
唉,都市人才啊。怎麽想到的
【Leetcode】338. Bit位計數