Count Set Bits Brian Kernighan Algorithm in DSA Python - Time & Space Complexity
We want to understand how fast the Brian Kernighan algorithm counts the number of 1s in a binary number.
How does the time taken grow as the number gets bigger?
Analyze the time complexity of the following code snippet.
def count_set_bits(n: int) -> int:
count = 0
while n:
n &= (n - 1) # Remove the rightmost set bit
count += 1
return count
This code counts how many bits are set to 1 in the binary form of the number n.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop runs once for each set bit in n.
- How many times: Equal to the number of 1s in the binary representation of n.
The number of loop runs depends on how many 1s are in n, not the total number of bits.
| Input Size (n) | Approx. Operations (loop runs) |
|---|---|
| 10 (binary 1010) | 2 |
| 100 (binary 1100100) | 3 |
| 1000 (binary 1111101000) | 6 |
Pattern observation: The loop count grows with the number of set bits, which can be much less than total bits.
Time Complexity: O(k) where k is the number of set bits in n.
This means the time depends on how many 1s are in the number, not its size in bits.
[X] Wrong: "The loop runs once for every bit in the number (total bits)."
[OK] Correct: The loop only runs for set bits, skipping zeros quickly, so it can be much faster.
Knowing this algorithm shows you can optimize counting bits by focusing on set bits only, a useful skill in many coding problems.
"What if we changed the input to always have half of its bits set? How would the time complexity change?"
Practice
Solution
Step 1: Understand the algorithm's main operation
The Brian Kernighan algorithm clears the least significant set bit in each iteration by doing n = n & (n-1).Step 2: Effect of clearing bits
Each clearing reduces the number of set bits by one until the number becomes zero, counting how many bits were set.Final Answer:
It repeatedly clears the least significant set bit until the number becomes zero. -> Option DQuick Check:
Clearing bits counts set bits [OK]
- Thinking it counts all digits, not just set bits
- Confusing bit shifting with bit clearing
- Counting characters in string form of number
Solution
Step 1: Identify the bit clearing operation
The correct operation to clear the least significant set bit is n = n & (n - 1).Step 2: Understand why other options are incorrect
Using OR, XOR, or addition does not clear the least significant set bit correctly.Final Answer:
n = n & (n - 1) -> Option AQuick Check:
Bit clear uses AND with n-1 [OK]
- Using OR instead of AND
- Using XOR which toggles bits
- Adding numbers instead of bitwise operations
def count_set_bits(n):
count = 0
while n:
n = n & (n - 1)
count += 1
return count
print(count_set_bits(13))Solution
Step 1: Convert 13 to binary
13 in binary is 1101, which has three set bits (1s).Step 2: Count set bits using the algorithm
Each iteration clears one set bit: 1101 -> 1100 -> 1000 -> 0000, total 3 times.Final Answer:
3 -> Option AQuick Check:
Binary 1101 has 3 set bits [OK]
- Counting total bits instead of set bits
- Miscounting binary digits
- Confusing decimal with binary
def count_set_bits(n):
count = 0
while n > 0:
n = n & (n + 1)
count += 1
return count
print(count_set_bits(7))Solution
Step 1: Identify the bit clearing operation
The code uses n & (n + 1), which does not clear the least significant set bit correctly.Step 2: Correct operation for clearing bits
The correct operation is n = n & (n - 1) to clear the rightmost set bit.Final Answer:
Using n & (n + 1) instead of n & (n - 1) -> Option CQuick Check:
Use n & (n - 1) to clear bits [OK]
- Using n & (n + 1) which is incorrect
- Confusing loop condition syntax
- Forgetting to initialize count
nums = [3, 5, 7]
A) def count_bits_list(nums):
return [bin(n).count('1') for n in nums]
B) def count_bits_list(nums):
def count_set_bits(n):
count = 0
while n:
n = n & (n - 1)
count += 1
return count
return [count_set_bits(n) for n in nums]
C) def count_bits_list(nums):
return [sum(int(d) for d in str(n)) for n in nums]
D) def count_bits_list(nums):
return [len(str(n)) for n in nums]Solution
Step 1: Analyze the code snippets
The first snippet uses Python's bin(n).count('1'), which counts set bits but not Brian Kernighan's algorithm. The second snippet implements the algorithm correctly using a while loop that clears the least significant set bit with n = n & (n - 1). The third sums the decimal digits, which is incorrect for bits. The fourth counts the length of the decimal string, also incorrect.Step 2: Confirm correct implementation
The second snippet defines count_set_bits using n = n & (n - 1) in a loop and applies it to each number via list comprehension, which is the proper use of Brian Kernighan's algorithm.Final Answer:
Option B uses Brian Kernighan's algorithm correctly. -> Option BQuick Check:
Correctly uses n & (n-1) loop [OK]
- Using string digit sums instead of bits
- Counting decimal digits instead of set bits
- Confusing built-in binary count with algorithm
Ready to prove it?
Pass the test and this pattern moves unknown
