Count Set Bits Brian Kernighan Algorithm in DSA Typescript - 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.
function countSetBits(n: number): number {
let count = 0;
while (n !== 0) {
n = n & (n - 1);
count++;
}
return count;
}
This code counts how many bits are set to 1 in the binary form of the number n by repeatedly turning off the rightmost set bit.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that clears the rightmost set bit each time.
- How many times: The loop runs once for each set bit (1) in the number.
Execution depends on how many 1s are in the number, not its size in bits.
| Input Size (n) | Approx. Operations (loop runs) |
|---|---|
| 10 (binary 1010) | 2 |
| 15 (binary 1111) | 4 |
| 1023 (binary 1111111111) | 10 |
Pattern observation: The number of operations equals the count of 1 bits, which can be much less than total bits.
Time Complexity: O(k)
This means the time grows with the number of set bits (k), not the total bits in the number.
[X] Wrong: "The loop runs once for every bit in the number (total bits)."
[OK] Correct: The loop only runs for each 1 bit, skipping zeros, so it can be much faster.
Knowing this algorithm shows you understand bit manipulation and efficient counting, a useful skill in many coding problems.
What if we changed the input to always have only one set bit? 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 set bits were present.Final Answer:
It repeatedly clears the least significant set bit until the number becomes zero. -> Option AQuick Check:
Clearing bits one by one counts set bits [OK]
- Confusing bit count with digit count
- Using simple right shifts without bit checks
- Ignoring bitwise AND operation
n?Solution
Step 1: Identify the bitwise operation to clear least set bit
The operation n = n & (n - 1) clears the least significant set bit in n.Step 2: Verify other options
OR, XOR, and addition do not clear the least significant set bit correctly.Final Answer:
n = n & (n - 1); -> Option BQuick Check:
AND with (n-1) clears least set bit [OK]
- Using OR or XOR instead of AND
- Adding numbers instead of bitwise operations
- Missing parentheses around (n - 1)
function countSetBits(n: number): number {
let count = 0;
while (n > 0) {
n = n & (n - 1);
count++;
}
return count;
}
console.log(countSetBits(13));Solution
Step 1: Convert 13 to binary and count set bits
13 in binary is 1101, which has three set bits (1,1,0,1).Step 2: Apply Brian Kernighan algorithm steps
Each iteration clears one set bit, so count increments 3 times until n becomes 0.Final Answer:
3 -> Option AQuick Check:
Number of 1s in 1101 = 3 [OK]
- Counting total bits instead of set bits
- Misunderstanding binary representation
- Off-by-one errors in loop count
function countSetBits(n: number): number {
let count = 0;
while (n != 0) {
n = n & n - 1;
count++;
}
return count;
}Solution
Step 1: Analyze the expression inside the loop
The expression n = n & n - 1 lacks parentheses, so it is evaluated as (n & n) - 1, which is incorrect.Step 2: Correct expression
It should be n = n & (n - 1) to correctly clear the least significant set bit.Final Answer:
Missing parentheses around (n - 1) in the expression. -> Option DQuick Check:
Parentheses ensure correct order of operations [OK]
- Using != 0 causing potential infinite loop for negatives
- Assuming both conditions always equivalent
- Operator precedence confusion causing wrong calculation
[5, 7, 10], which TypeScript code correctly uses Brian Kernighan's algorithm to return an array of their set bit counts?Solution
Step 1: Understand Brian Kernighan's algorithm usage
const counts = arr.map(n => { let count = 0; while (n > 0) { n = n & (n - 1); count++; } return count; }); uses the correct loop with n = n & (n - 1) to count set bits for each number.Step 2: Check other options for correctness
const counts = arr.map(n => n.toString(2).length); counts total binary digits, not set bits. const counts = arr.map(n => { let count = 0; while (n > 0) { n = n >> 1; count++; } return count; }); counts total bits by shifting, not set bits. const counts = arr.map(n => { let count = 0; for (let i = 0; i < 32; i++) { if ((n & (1 << i)) !== 0) count++; } return count; }); uses a loop checking each bit, which works but is not Brian Kernighan's algorithm.Final Answer:
const counts = arr.map(n => { let count = 0; while (n > 0) { n = n & (n - 1); count++; } return count; }); -> Option CQuick Check:
Use n & (n-1) loop inside map for set bits [OK]
- Counting binary string length instead of set bits
- Using right shift without bit check
- Confusing bitwise loop with simple iteration
Ready to prove it?
Pass the test and this pattern moves unknown
