23.位元位計數-Leetcode 338(python)
阿新 • • 發佈:2018-12-05
- 題目描述
給定一個非負整數 num。對於 0 ≤ i ≤ num 範圍中的每個數字 i ,計算其二進位制數中的 1 的數目並將它們作為陣列返回。
- 示例
示例 1:
輸入: 2
輸出: [0,1,1]
示例 2:
輸入: 5
輸出: [0,1,1,2,1,2]
進階:
給出時間複雜度為O(n*sizeof(integer))的解答非常容易。但你可以線上性時間O(n)內用一趟掃描做到嗎?
要求演算法的空間複雜度為O(n)。
你能進一步完善解法嗎?要求在C++或任何其他語言中不使用任何內建函式(如 C++ 中的 __builtin_popcount)來執行此操作。
- 解決思路
一開始看到通過率那麼高,興致盎然要自己做出來,然後從0到15的二進位制數寫完了,愣是看不出有啥規律,腦子裡沒有那種意識,咋都沒辦法。網上大神的解決方案:觀察發現,1的二進位制中數字1的個數是0的加1(),2和3的是0和1的分別加1,4567的是0123的分別加1。找到一種神奇的規律。
0 0 0
1 1 1
2 10 1
3 11 2
4 100 1
5 101 2
6 110 2
7 111 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
- 程式碼
class Solution(object): def countBits(self, num): """ :type num: int :rtype: List[int] """ List1 = [0] while(len(List1)<=num): List2 = [i+1 for i in List1] List1 = List1 + List2 return List1[:num+1]
- 解決思路二
觀察發現:偶數的二進位制中1的個數和其一半的數的二進位制個數相等,奇數的二進位制中1的個數是其一半的數的二進位制中1的個數加1.比如2和4都是1,3和6都是2。5是2,2是1;7是3,3是2.
另外,整數對應的二進位制數邏輯右移一位,就等於除2操作。
- 程式碼二
class Solution(object):
def countBits(self, num):
"""
:type num: int
:rtype: List[int]
"""
List1 = [0]
for i in range(1,num+1):
#>>1為邏輯右移1位,等於除2操作
#偶數對2取餘為0,奇數對2取餘為1
List1.append(List1[i>>1]+(i%2))
return List1