Skip to content

Commit 51b6979

Browse files
committed
feat(algorithms, dynamic-programming): counting bits
1 parent e6eb579 commit 51b6979

24 files changed

+290
-0
lines changed

puzzles/climb_stairs/README.md renamed to algorithms/dynamic_programming/climb_stairs/README.md

File renamed without changes.

puzzles/climb_stairs/__init__.py renamed to algorithms/dynamic_programming/climb_stairs/__init__.py

File renamed without changes.

puzzles/climb_stairs/test_climb_stairs.py renamed to algorithms/dynamic_programming/climb_stairs/test_climb_stairs.py

File renamed without changes.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Counting Bits
2+
3+
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
4+
in the binary representation of i.
5+
6+
## Examples
7+
8+
```text
9+
Example 1:
10+
11+
Input: n = 2
12+
Output: [0,1,1]
13+
Explanation:
14+
0 --> 0
15+
1 --> 1
16+
2 --> 10
17+
```
18+
19+
```
20+
Example 2:
21+
22+
Input: n = 5
23+
Output: [0,1,1,2,1,2]
24+
Explanation:
25+
0 --> 0
26+
1 --> 1
27+
2 --> 10
28+
3 --> 11
29+
4 --> 100
30+
5 --> 101
31+
```
32+
33+
## Constraints
34+
35+
- 0 <= `n` <= 10^5
36+
37+
## Solution
38+
39+
This solution uses a bottom-up dynamic programming approach to solve the problem.
40+
The key to this problem lies in the fact that any binary number can be broken down into two parts: the least-significant
41+
(rightmost bit), and the rest of the bits. The rest of the bits can be expressed as the binary number divided by 2
42+
(rounded down), or `i >> 1`.
43+
44+
For example:
45+
- 4 in binary = 100
46+
- rightmost bit = 0
47+
- rest of bits = 10, which is also (4 // 2) = 2 in binary.
48+
49+
When the number is odd,
50+
- 5 in binary = 101
51+
- rightmost bit = 1
52+
- rest of bits = 10, which is also (5 // 2) = 2 in binary.
53+
54+
in the binary representation of i is that number plus 1 if the rightmost bit is 1. We can tell if the last significant
55+
bit is 1 by checking if it is odd.
56+
57+
As an example, we know that the number of 1's in 2 is 1. This information can be used to calculate the number of 1's in 4.
58+
The number of 1's in 4 is the number of 1's in 2 plus 0, because 4 is even.
59+
60+
This establishes a recurrence relationship between the number of 1's in the binary representation of i and the number of
61+
1's in the binary representation of i // 2: if count[i] is the number of 1's in the binary representation of i, then
62+
count[i] = count[i // 2] + (i % 2).
63+
64+
With the recurrence relationship established, we can now solve the problem using a bottom-up dynamic programming approach.
65+
We start with the base case dp[0] = 0, and then build up the solution for dp[i] for i from 1 to n.
66+
67+
![Solution 1](./images/solutions/counting_bits_solution_1.png)
68+
![Solution 2](./images/solutions/counting_bits_solution_2.png)
69+
![Solution 3](./images/solutions/counting_bits_solution_3.png)
70+
![Solution 4](./images/solutions/counting_bits_solution_4.png)
71+
![Solution 5](./images/solutions/counting_bits_solution_5.png)
72+
![Solution 6](./images/solutions/counting_bits_solution_6.png)
73+
![Solution 7](./images/solutions/counting_bits_solution_7.png)
74+
![Solution 8](./images/solutions/counting_bits_solution_8.png)
75+
![Solution 9](./images/solutions/counting_bits_solution_9.png)
76+
![Solution 10](./images/solutions/counting_bits_solution_10.png)
77+
![Solution 11](./images/solutions/counting_bits_solution_11.png)
78+
![Solution 12](./images/solutions/counting_bits_solution_12.png)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from typing import List
2+
3+
4+
def count_bits(n: int) -> List[int]:
5+
"""
6+
Counts the number of 1 bits in the given integer provided returning a list where count[i] stores the count of '1'
7+
bits in the binary form of i.
8+
Args:
9+
n(int): integer
10+
Returns:
11+
list: count of 1 bits where each index contains the count of 1 bits
12+
"""
13+
dp = [0] * (n + 1)
14+
15+
for i in range(1, n + 1):
16+
# this can also be solved as which is faster in Python
17+
# dp[i] = dp[i >> 1] + (i & 1)
18+
dp[i] = dp[i // 2] + (i % 2)
19+
20+
return dp
36.1 KB
Loading
40 KB
Loading
52.2 KB
Loading
33.1 KB
Loading
42.3 KB
Loading

0 commit comments

Comments
 (0)