Example 1
ready- Input
n = 2- Expected
[ 0, 1, 1 ]- Why
- 0, 1, and 2 have 0, 1, and 1 set bits
One answer can unlock the next. If you already know the bit count for 6, you can use
it to find the bit count for 12 without inspecting 12 from scratch.
Given a non-negative integer n, return an array ans with one entry for every integer
from 0 through n. A set bit is a binary digit equal to 1; ans[i] must contain
the number of set bits in i.
A few ground rules:
n + 1 entries.i stores the answer for the integer i.ans[0] is always 0.0 <= n <= 100_000Hints
You can count a number's 1 digits by repeatedly checking its last binary digit,
then shifting the number right. Doing that for every value gives you a solid first
solution.
Shifting i right once produces i >> 1. You've already computed that smaller
number's answer by the time you reach i.
The dropped digit is i & 1, either 0 or 1. Combine both observations:
ans[i] = ans[i >> 1] + (i & 1).
Can you produce every answer in one pass without converting any number to a binary string?
Visible cases
n = 2[
0,
1,
1
]n = 5[
0,
1,
1,
2,
1,
2
]n = 8[
0,
1,
1,
2,
1,
2,
2,
3,
1
]Interview signal
Treat each integer as a separate popcount, the number of set bits in one value. Read
its last binary digit with value & 1, add that digit to the count, then shift right
until nothing remains.
def count_bits(n: int) -> list[int]:
answer: list[int] = []
for number in range(n + 1):
value = number
bits = 0
while value > 0:
bits += value & 1
value >>= 1
answer.append(bits)
return answerAn integer up to n has O(log n) binary digits, and you repeat that work for all
n + 1 integers. Time O(n log n). Space O(n) for the returned array, with O(1)
extra working space.
Dynamic programming (DP) stores answers to smaller subproblems so a larger answer can
reuse them. Shifting i right removes its last binary digit and produces a smaller index:
i >> 1. The removed digit is exactly i & 1.
The transition is the rule that builds one DP answer from earlier answers. Here it is:
ans[i] = ans[i >> 1] + (i & 1)
def count_bits(n: int) -> list[int]:
ans = [0] * (n + 1)
for i in range(1, n + 1):
ans[i] = ans[i >> 1] + (i & 1)
return ansEvery entry now takes constant work. The base case ans[0] = 0 is already in place,
and every transition reads an earlier entry.
Time O(n). Space O(n) for the returned DP array, with O(1) extra working space.
Ready to run.
3 cases are queued.
Visible testcase
Case 1
Expected
[ 0, 1, 1 ]