Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to count total number of set bits of all numbers in range 0 to n in Python
Suppose we have a number n. For each number i in the range 0 ? i ? n, we need to count the number of set bits (1's) in their binary representation and return the total count. For example, if n = 5, the numbers are [0, 1, 2, 3, 4, 5] with binary representations [0, 1, 10, 11, 100, 101]. The count of 1's are [0, 1, 1, 2, 1, 2], so the total is 7.
Approach
We use dynamic programming with bit manipulation. The key insight is that for any number i, if i & (i-1) == 0, then i is a power of 2. We can build the solution incrementally ?
Create an array to store count of set bits for each number
Use an offset to track position relative to the nearest power of 2
For powers of 2, set count to 1 and reset offset
For other numbers, use previously computed values
Example
class Solution:
def countBits(self, n):
result = [0] * (n + 1)
offset = 0
for i in range(1, n + 1):
if i & (i - 1) == 0: # i is power of 2
result[i] = 1
offset = 0
else:
offset += 1
result[i] = 1 + result[offset]
return sum(result)
# Test the solution
solution = Solution()
print("Total set bits for n = 5:", solution.countBits(5))
# Let's see the breakdown
def show_breakdown(n):
result = [0] * (n + 1)
offset = 0
print(f"Number | Binary | Set Bits")
print("-------|--------|----------")
print(f" 0 | 0 | 0")
for i in range(1, n + 1):
if i & (i - 1) == 0:
result[i] = 1
offset = 0
else:
offset += 1
result[i] = 1 + result[offset]
print(f" {i} | {bin(i)[2:]:>3} | {result[i]}")
print(f"\nTotal: {sum(result)}")
show_breakdown(5)
Total set bits for n = 5: 7 Number | Binary | Set Bits -------|--------|---------- 0 | 0 | 0 1 | 1 | 1 2 | 10 | 1 3 | 11 | 2 4 | 100 | 1 5 | 101 | 2 Total: 7
How It Works
The algorithm uses the property that for any number i:
If i is a power of 2 (i & (i-1) == 0), it has exactly one set bit
Otherwise, we can use previously computed values with offset tracking
The offset helps map current number to a smaller number whose set bits we already know
Alternative Approach Using Built-in Function
def count_set_bits_simple(n):
total = 0
for i in range(n + 1):
total += bin(i).count('1')
return total
# Test both approaches
n = 5
print(f"Using DP approach: {Solution().countBits(n)}")
print(f"Using simple approach: {count_set_bits_simple(n)}")
Using DP approach: 7 Using simple approach: 7
Comparison
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Dynamic Programming | O(n) | O(n) | Optimal performance |
| Built-in count | O(n log n) | O(1) | Simple implementation |
Conclusion
The dynamic programming approach efficiently counts set bits by leveraging bit manipulation properties. Use the DP method for optimal O(n) time complexity, or the simple approach for readability.
