Counting Bits
Problem
https://leetcode.com/problems/counting-bits/
Given an integer n, return an array ans of length n + 1
such that for each i (0 <= i <= n), ans[i] is the
number of 1‘s in the binary representation of i.
Example 1:
Input: n = 2
Output: [0,1,1]
Explanation:
0 --> 0
1 --> 1
2 --> 10
Example 2:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
Constraints:
0 <= n <= 105
Pattern
Bit Manipulation, Dynamic Programming
Approaches
Explanation
The most straight forward solution is to go through \(0, 1, \dots, n\)
and count the number of bits in each integer. We can use either the Brian
Kernighan method (count how many times we do num = num & (num - 1)) or
the Bit Scan method which goes through each bit position and checks if it
is 0 or 1 (add 1 if (i << 1) & num) > 0 for all 32 bit positions i).
We use the Brian Kernighan method as it is faster. Each bit count is
appeneded to a list which is our result.
Code
def countBits(n: int) -> list[int]:
"""Return the number of 1-bits for each integer from 0 to n."""
result = []
for i in range(n + 1):
bits = 0
num = i
while num > 0:
num = num & (num - 1)
bits += 1
result.append(bits)
return result
Test
>>> from counting_bits__bit_counting import countBits
>>> countBits(2)
[0, 1, 1]
>>> countBits(5)
[0, 1, 1, 2, 1, 2]
>>> countBits(0)
[0]
Complexity
Measure |
Complexity |
Notes |
|---|---|---|
Time |
\(O(n)\) |
outer loop goes 0 to n, inner loop is at most 32 iterations |
Auxiliary Space |
\(O(1)\) |
- counting_bits__bit_counting.countBits(n: int) list[int]
Return the number of 1-bits for each integer from 0 to n.
Explanation
Observe that the number of bits in an integer \(n\) is equal to the
number of bits in the right bitshifted integer n >> 1 plus whether the
last bit was 1. We can use dynamic programming to create the array counting
the number of 1s in the binary representation of the numbers
\(0, \dots, n\) with 0 having 0 bits as our base case.
Code
def countBits(n: int) -> list[int]:
"""Return the number of 1-bits for each integer from 0 to n."""
bits = [0] * (n + 1)
for i in range(n + 1):
bits[i] = bits[i >> 1] + (1 & i)
return bits
Test
>>> from counting_bits__dynamic_programming import countBits
>>> countBits(2)
[0, 1, 1]
>>> countBits(5)
[0, 1, 1, 2, 1, 2]
>>> countBits(0)
[0]
Complexity
Measure |
Complexity |
Notes |
|---|---|---|
Time |
\(O(n)\) |
one loop to create the array |
Auxiliary Space |
\(O(1)\) |
- counting_bits__dynamic_programming.countBits(n: int) list[int]
Return the number of 1-bits for each integer from 0 to n.