Facebook Pixel

2220. Minimum Bit Flips to Convert Number

EasyBit Manipulation
Leetcode Link

Problem Description

You are given two integers start and goal. A bit flip operation allows you to choose any bit in the binary representation of a number and change it from 0 to 1 or from 1 to 0.

For example, if you have the number 7 (binary: 111):

  • Flipping the rightmost bit gives 110 (decimal: 6)
  • Flipping the middle bit gives 101 (decimal: 5)
  • Flipping a leading zero (like the 5th bit from the right) gives 10111 (decimal: 23)

Your task is to find the minimum number of bit flips needed to transform start into goal.

The solution uses the XOR operation (start ^ goal) to identify which bits are different between the two numbers. The XOR operation returns 1 for positions where the bits differ and 0 where they are the same. By counting the number of 1s in the XOR result using bit_count(), we get the minimum number of flips required.

For instance, if start = 10 (binary: 1010) and goal = 7 (binary: 0111):

  • 10 ^ 7 = 1010 ^ 0111 = 1101
  • The result has three 1s, meaning 3 bits need to be flipped to convert 10 to 7
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is recognizing that we need to flip a bit only when the corresponding bits in start and goal are different. If both numbers have the same bit at a position (both 0 or both 1), no flip is needed. If they differ (one is 0 and the other is 1), we need exactly one flip at that position.

This naturally leads us to think about the XOR operation, which is perfectly suited for detecting differences between bits. The XOR operation (^) returns 1 when two bits are different and 0 when they're the same:

  • 0 ^ 0 = 0 (same, no flip needed)
  • 1 ^ 1 = 0 (same, no flip needed)
  • 0 ^ 1 = 1 (different, flip needed)
  • 1 ^ 0 = 1 (different, flip needed)

By performing start ^ goal, we create a new number where each 1 bit represents a position that needs to be flipped. The total number of flips required is simply the count of 1s in this XOR result.

For example, with start = 3 (binary: 011) and goal = 4 (binary: 100):

  • 3 ^ 4 = 011 ^ 100 = 111
  • The result has three 1s, indicating we need to flip all three bits

This approach gives us the minimum number of flips because each differing bit position requires exactly one flip - there's no way to change a bit from 0 to 1 or vice versa without flipping it once.

Solution Approach

The implementation is straightforward once we understand that XOR identifies the differing bits between start and goal.

The solution uses bit manipulation to solve the problem in a single line:

  1. XOR Operation: start ^ goal

    • This performs a bitwise XOR between start and goal
    • The result is a number where each 1 bit indicates a position where start and goal differ
    • Each 0 bit indicates a position where they are the same
  2. Count the 1s: .bit_count()

    • Python's built-in bit_count() method counts the number of 1 bits in the binary representation
    • This gives us the exact number of bits that need to be flipped

The algorithm works as follows:

  • When we XOR two numbers, we get a binary result where:
    • Bit is 1 if the corresponding bits in start and goal are different
    • Bit is 0 if the corresponding bits in start and goal are the same
  • Since each 1 in the XOR result represents a bit that needs to be flipped, counting all the 1s gives us the minimum number of flips required

Time Complexity: O(1) - The XOR operation and bit counting both operate in constant time for 32-bit integers.

Space Complexity: O(1) - We only use a constant amount of extra space to store the XOR result.

Example walkthrough with start = 10 and goal = 7:

  • Binary: start = 1010, goal = 0111
  • XOR: 1010 ^ 0111 = 1101
  • Count of 1s in 1101 = 3
  • Therefore, we need 3 bit flips to convert 10 to 7

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a small example with start = 3 and goal = 4.

Step 1: Convert to binary representation

  • start = 3 → binary: 011
  • goal = 4 → binary: 100

Step 2: Apply XOR operation to find differing bits

  011 (start = 3)
^ 100 (goal = 4)
-----
  111 (XOR result = 7)

The XOR operation compares each bit position:

  • Position 0 (rightmost): 1 ^ 0 = 1 (different, needs flip)
  • Position 1: 1 ^ 0 = 1 (different, needs flip)
  • Position 2: 0 ^ 1 = 1 (different, needs flip)

Step 3: Count the number of 1s in the XOR result

  • XOR result = 111 has three 1 bits
  • Therefore, we need 3 bit flips to transform 3 into 4

Verification: Let's verify by actually performing the flips on start = 3 (binary: 011):

  1. Flip bit at position 0: 011010 (decimal: 2)
  2. Flip bit at position 1: 010000 (decimal: 0)
  3. Flip bit at position 2: 000100 (decimal: 4) ✓

We successfully transformed 3 into 4 using exactly 3 bit flips, confirming our answer.

Solution Implementation

1class Solution:
2    def minBitFlips(self, start: int, goal: int) -> int:
3        # XOR operation finds bits that are different between start and goal
4        # A bit in the XOR result is 1 if the corresponding bits in start and goal differ
5        xor_result = start ^ goal
6      
7        # Count the number of 1s in the XOR result
8        # This represents the minimum number of bit flips needed
9        return xor_result.bit_count()
10```
11
12Alternative implementation without using `bit_count()` method (for compatibility with older Python versions):
13
14```python3
15class Solution:
16    def minBitFlips(self, start: int, goal: int) -> int:
17        # XOR operation finds bits that are different between start and goal
18        xor_result = start ^ goal
19      
20        # Count the number of set bits (1s) in the XOR result
21        count = 0
22        while xor_result:
23            # Check if the least significant bit is 1
24            count += xor_result & 1
25            # Right shift to check the next bit
26            xor_result >>= 1
27      
28        return count
29
1class Solution {
2    /**
3     * Calculates the minimum number of bit flips required to convert 'start' to 'goal'.
4     * 
5     * The approach uses XOR operation to identify differing bits between the two numbers.
6     * XOR returns 1 when bits are different and 0 when they are the same.
7     * Counting the number of 1s in the XOR result gives us the number of bit flips needed.
8     * 
9     * @param start The starting integer value
10     * @param goal The target integer value to convert to
11     * @return The minimum number of bit flips required
12     */
13    public int minBitFlips(int start, int goal) {
14        // XOR operation to find differing bits between start and goal
15        int xorResult = start ^ goal;
16      
17        // Count the number of set bits (1s) in the XOR result
18        // Each set bit represents a position where a flip is needed
19        return Integer.bitCount(xorResult);
20    }
21}
22
1class Solution {
2public:
3    /**
4     * Calculate the minimum number of bit flips needed to convert 'start' to 'goal'
5     * 
6     * @param start: The starting integer value
7     * @param goal: The target integer value to achieve
8     * @return: The minimum number of bit flips required
9     * 
10     * Algorithm:
11     * - XOR operation between start and goal gives us a number where each bit is 1
12     *   if the corresponding bits in start and goal are different
13     * - Counting the number of 1s in the XOR result gives us the number of bit flips needed
14     */
15    int minBitFlips(int start, int goal) {
16        // XOR to find differing bits, then count the number of set bits (1s)
17        return __builtin_popcount(start ^ goal);
18    }
19};
20
1/**
2 * Calculates the minimum number of bit flips required to convert start to goal
3 * @param start - The starting number
4 * @param goal - The target number
5 * @returns The minimum number of bit flips needed
6 */
7function minBitFlips(start: number, goal: number): number {
8    // XOR gives us a bit pattern where 1s represent positions that differ
9    // Count the number of 1s in the XOR result
10    return bitCount(start ^ goal);
11}
12
13/**
14 * Counts the number of set bits (1s) in a number using Brian Kernighan's algorithm
15 * This is an optimized bit counting algorithm that works in O(log n) time
16 * @param i - The number to count bits in
17 * @returns The count of set bits
18 */
19function bitCount(i: number): number {
20    // Step 1: Count bits in groups of 2
21    // Subtract the number of bits shifted right by 1 (handles pairs)
22    i = i - ((i >>> 1) & 0x55555555);
23  
24    // Step 2: Sum adjacent pairs of 2-bit counts into 4-bit counts
25    // 0x33333333 = 0011 0011 0011... in binary
26    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
27  
28    // Step 3: Sum adjacent pairs of 4-bit counts into 8-bit counts
29    // 0x0f0f0f0f = 0000 1111 0000 1111... in binary
30    i = (i + (i >>> 4)) & 0x0f0f0f0f;
31  
32    // Step 4: Sum all 8-bit counts together
33    // Add bytes together by shifting and adding
34    i = i + (i >>> 8);
35    i = i + (i >>> 16);
36  
37    // Step 5: Return only the lowest 6 bits (max count is 32 for a 32-bit number)
38    // 0x3f = 63 in decimal, enough to hold count up to 32
39    return i & 0x3f;
40}
41

Time and Space Complexity

The time complexity is O(log n), where n is the maximum value between start and goal. The XOR operation start ^ goal takes O(1) time for fixed-size integers, but the bit_count() method needs to count the number of set bits (1s) in the result. This counting process examines each bit position, and since an integer n has approximately log n bits in its binary representation, the time complexity is O(log n).

The space complexity is O(1). The algorithm only uses a constant amount of extra space to store the XOR result and perform the bit counting operation, regardless of the input size.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Misunderstanding XOR Operation with Negative Numbers

A common mistake is assuming the solution works identically for negative numbers without considering their two's complement representation. In Python, negative integers have an infinite sequence of leading 1s in their binary representation.

Problem Example:

start = -1  # Binary: ...11111111 (all 1s)
goal = 0    # Binary: ...00000000 (all 0s)

If you try to count bit flips naively, the XOR would theoretically have infinite 1s.

Solution: Python's bit_count() method handles this correctly by only counting the 1s in the actual stored bits. However, if implementing manually, you need to mask the result to a fixed bit width:

class Solution:
    def minBitFlips(self, start: int, goal: int) -> int:
        # For 32-bit integers, mask the result
        xor_result = (start ^ goal) & 0xFFFFFFFF
      
        count = 0
        while xor_result:
            count += xor_result & 1
            xor_result >>= 1
      
        return count

2. Manual Bit Counting with Brian Kernighan's Algorithm

When implementing manual bit counting, developers often use a basic loop that checks every bit. A more efficient approach uses Brian Kernighan's algorithm:

Inefficient approach:

# Checks every bit position even if many are 0
count = 0
while xor_result:
    count += xor_result & 1
    xor_result >>= 1

Optimized approach:

class Solution:
    def minBitFlips(self, start: int, goal: int) -> int:
        xor_result = start ^ goal
        count = 0
      
        # Brian Kernighan's algorithm - only iterates for each set bit
        while xor_result:
            xor_result &= xor_result - 1  # Clears the rightmost set bit
            count += 1
      
        return count

This optimization reduces iterations from O(log n) to O(k) where k is the number of set bits.

3. Assuming Leading Zeros Don't Matter

Some developers might think that flipping leading zeros is unnecessary or shouldn't be counted. However, the problem clearly states that any bit can be flipped, including leading zeros.

Incorrect assumption:

# Wrong: Trying to "normalize" the numbers first
start = 10  # 1010
goal = 23   # 10111
# Some might think to align them as 01010 and 10111

Correct understanding: The XOR operation naturally handles this - it compares all corresponding bit positions, treating missing higher-order bits as zeros automatically.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More