こんにちは
今回の学びは
・落ち着いて法則性をみつけだそう
・full_adderでcarryが発生するかどうかで1bitsを割り出せる
問題は。。。
(時間配分は5分問題理解 10分検討 10分実装 20分振り返り の一文45分構成)
まずは入出力をしっかりおさえましょう。
この問題の基礎問といっていいと思うのですが簡単だったので
記事にはしていないのですがnumber of 1bitsという問題をやりました

で
今回のcounting bitsはその数字を0から舐めて
数字ごとにnumber of 1bitsを出してよ。という欲張りな問題。
上の、Next challengeからも唯一のmedium問題のようです
なにか、
なにか法則性を見つけ出そうと
かいてみるわけですが中々たどりつきませんでしたね。ー
それでも
いくつか、見つかりました
1が増えるのを、直前の数字から割り出すことはできないものか?
・キャリオーバーした数 - 1 、1が増える
・一の位が1の時は必ず1増える
・1000とか桁繰り上がりのときは1が一個になる。(当初は桁くらい上がりで1増える、と考えていた)
という法則を実装することにした。桁繰り上がりの判断に以前、問題easy 371 sum of two integerにて、やったhalf_adderを利用することにした。
実装前後でこれは毎回書きましょう。timespace analysis (時間とスペースの分析)は O(N * 32)
実際の実装はこちら
full_adderやgetNCarryは割愛、easy 371 sum of two integerを参考にしてほしい
def countBits(self, num: int) -> List[int]:
counter = 0
j = 1 # 桁が増えたかどうかの判定用
p = 0
ans = []
for i in range(0, num+1):
if i == 0:
ans.append(0)
else:
keta = 2**j
if i == keta:
j += 1
counter = 1
else:
if i & 1 == 1: # 0から1へ、第一位がなった時
counter += 1
number_of_carryover = self.getNCarry(p, 1)
if number_of_carryover >= 2:
counter -= (number_of_carryover-1)
ans.append(counter)
p = i
return ans
実装後です。timespace analysis (時間とスペースの分析)は O(N)です

まとめ
・落ち着いて法則性をみつけだそう
・full_adderでcarryが発生するかどうかで1bitsを割り出せる
以上です