Bit Manipulation Technique in DSA

Bit Manipulation in a Nutshell

What is the Bit Manipulation Technique?

Bit Manipulation is a powerful technique in DSA where we use binary operations to solve problems efficiently. It's commonly used in problems related to power-of-two checks, counting bits, generating subsets, toggling bits, and more.

It relies on bitwise operators like:

Key Bit Manipulation Operations

1. Check if a Number is a Power of Two — Explained for Beginners

To determine if a number is a power of two using bit manipulation, we rely on the fact that powers of two have a very unique pattern in binary:

Notice a pattern? Every power of two has exactly one bit set to 1 and all other bits are 0.

This is the key to our trick: if a number n is a power of two, then n has exactly one set bit. And here’s what happens when you subtract 1 from such a number:

Now, let’s perform a bitwise AND between n and n - 1:

  1000  (8)
& 0111  (7)
= 0000

The result is 0. This will only happen for numbers that are powers of two.

Step-by-Step Breakdown:

  1. Check if n is greater than 0 (since 0 and negatives are not powers of 2).
  2. Use bitwise AND: n & (n - 1)
  3. If the result is 0, then n is a power of 2. Otherwise, it’s not.

Why Bit Manipulation?

Bit manipulation provides an incredibly fast and elegant solution here. Instead of looping or dividing repeatedly to check powers of 2, we do just one & operation:

This is far more efficient than traditional methods like looping, especially for performance-critical applications like embedded systems, competitive programming, and large-scale simulations.

Pseudocode

// Pseudocode
function isPowerOfTwo(n):
    return n > 0 and (n & (n - 1)) == 0

Examples:

Note: This method only works for positive integers. If n ≤ 0, it's not a power of 2.

2. Count the Number of Set Bits (1s)

Count how many bits are set to 1 in the binary representation of a number.

// Pseudocode
function countSetBits(n):
    count = 0
    while n != 0:
        n = n & (n - 1)
        count += 1
    return count

Explanation: Each iteration clears the rightmost set bit.

3. Toggle a Bit at Position k

Flip the bit at position k (0-based from right).

// Pseudocode
function toggleBit(n, k):
    return n ^ (1 << k)

4. Check if the k-th Bit is Set

Check if bit at position k is 1.

// Pseudocode
function isKthBitSet(n, k):
    return (n & (1 << k)) != 0

5. Turn Off the Rightmost Set Bit

// Pseudocode
function turnOffRightmostBit(n):
    return n & (n - 1)

6. Get the Rightmost Set Bit

// Pseudocode
function getRightmostSetBit(n):
    return n & -n

Explanation: -n is the two's complement of n.

Common Use Cases of Bit Manipulation

Example: Find the Unique Element

Given an array where every element appears twice except one, find the unique one.

// Pseudocode
function findUnique(arr):
    result = 0
    for num in arr:
        result = result ^ num
    return result

Why it works: XOR cancels out pairs (a ^ a = 0), and 0 ^ b = b.

Time and Space Complexity

Advantages of Bit Manipulation

Disadvantages

Conclusion

Bit Manipulation is an efficient and low-level technique in DSA. It is particularly useful when solving problems related to flags, parity, and optimization. Mastering bit operations can lead to elegant and performant solutions for a variety of tricky problems.