LeetCode 2220 - Minimum Bit Flips to Convert Number
The problem asks us to determine the minimum number of bit flips required to transform an integer start into another integer goal. A bit flip is defined as changing a single bit in the binary representation of a number from 0 to 1 or from 1 to 0.
Difficulty: 🟢 Easy
Topics: Bit Manipulation
Solution
Problem Understanding
The problem asks us to determine the minimum number of bit flips required to transform an integer start into another integer goal. A bit flip is defined as changing a single bit in the binary representation of a number from 0 to 1 or from 1 to 0. The input consists of two non-negative integers start and goal, both of which can range up to $10^9$. The expected output is a single integer representing the minimum number of flips needed.
Essentially, the problem is asking for the number of positions in the binary representations of start and goal where the bits differ. This is equivalent to calculating the Hamming distance between the two numbers.
Key considerations include handling numbers with different bit lengths, numbers that are equal (resulting in zero flips), and very large numbers up to 30 bits (since $10^9 < 2^{30}$). Edge cases might include start or goal being zero or one being significantly larger than the other.
Approaches
The brute-force approach involves converting both start and goal into their binary string representations, aligning their lengths, and then iterating through each bit to count differences. While this works, it involves string manipulation and bit-by-bit comparison, which is unnecessary because bitwise operators are available. This approach has linear time complexity relative to the number of bits, but it is not optimal due to the overhead of string operations.
The optimal approach leverages the bitwise XOR operation. XOR between two bits is 1 if the bits differ and 0 if they are the same. Thus, start ^ goal produces a number where each 1 represents a bit that needs to be flipped. Counting the number of 1s in this XOR result gives the minimum number of flips. This is efficient because it directly works at the bit level without any conversion to strings.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(B) | O(B) | Convert numbers to binary strings and compare each bit |
| Optimal | O(B) | O(1) | Use XOR to identify differing bits and count set bits |
Here, $B$ represents the number of bits needed to represent the numbers, which is at most 30 for the given constraints.
Algorithm Walkthrough
- Compute the XOR of
startandgoal. This gives a number where each1represents a bit that differs between the two numbers. - Initialize a counter
flipsto zero to track the number of differing bits. - While the XOR result is greater than zero, repeatedly remove the least significant
1usingxor &= xor - 1. Incrementflipseach time. This technique counts the number of set bits efficiently. - Once all
1s have been removed, the counterflipscontains the minimum number of bit flips required. - Return
flipsas the result.
Why it works: XOR produces a binary number where each 1 indicates a position that differs between start and goal. Counting all such 1s gives the exact number of bits that need to be flipped. The property x & (x - 1) clears the lowest set bit efficiently, ensuring all differing bits are counted.
Python Solution
class Solution:
def minBitFlips(self, start: int, goal: int) -> int:
xor = start ^ goal
flips = 0
while xor:
xor &= xor - 1
flips += 1
return flips
The Python implementation computes the XOR of start and goal to identify differing bits. It then counts the number of set bits using a loop with the efficient xor &= xor - 1 trick. Each iteration removes one set bit and increments the flips counter until no set bits remain.
Go Solution
func minBitFlips(start int, goal int) int {
xor := start ^ goal
flips := 0
for xor != 0 {
xor &= xor - 1
flips++
}
return flips
}
In Go, the implementation is essentially the same as in Python. Go uses int for integers, and bitwise operations work directly on integers. The loop counts set bits in the XOR result using the same efficient bit-clearing method.
Worked Examples
Example 1: start = 10, goal = 7
Binary representations: 10 = 1010, 7 = 0111
- XOR:
1010 ^ 0111 = 1101 - Count set bits in
1101: 3
Result: 3 flips.
Example 2: start = 3, goal = 4
Binary representations: 3 = 011, 4 = 100
- XOR:
011 ^ 100 = 111 - Count set bits in
111: 3
Result: 3 flips.
| Step | XOR Value | Flips Count |
|---|---|---|
| Initial | 1010 ^ 0111 = 1101 | 0 |
| Remove lowest 1 | 1100 | 1 |
| Remove lowest 1 | 1000 | 2 |
| Remove lowest 1 | 0000 | 3 |
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(B) | B is the number of bits in the XOR result, maximum 30 |
| Space | O(1) | Only a few integer variables are used |
The algorithm is efficient because it processes only the set bits in the XOR result. Given the constraint $0 \leq start, goal \leq 10^9$, the number of bits never exceeds 30, making the approach effectively constant time in practice.
Test Cases
# Basic test cases from the problem
assert Solution().minBitFlips(10, 7) == 3 # 1010 -> 0111
assert Solution().minBitFlips(3, 4) == 3 # 011 -> 100
# Edge cases
assert Solution().minBitFlips(0, 0) == 0 # no flips needed
assert Solution().minBitFlips(0, 1) == 1 # only one flip
assert Solution().minBitFlips(1, 0) == 1 # only one flip
# Large numbers
assert Solution().minBitFlips(10**9, 0) == 30 # 30-bit number
assert Solution().minBitFlips(10**9, 10**9) == 0 # same number, zero flips
# Different bit lengths
assert Solution().minBitFlips(1, 8) == 2 # 0001 -> 1000, 2 flips
| Test | Why |
|---|---|
| 10,7 | Provided example with multiple flips |
| 3,4 | Provided example with multiple flips |
| 0,0 | Minimal input, no flips |
| 0,1 and 1,0 | Single bit difference, minimal flips |
| 10^9,0 | Maximum input, test large numbers |
| 10^9,10^9 | Identical numbers, expect zero flips |
| 1,8 | Different bit lengths, verify correct bit counting |
Edge Cases
- Start and goal are the same: This is a potential source of error if the implementation incorrectly counts flips even when numbers are equal. The correct output is zero flips because XOR of two identical numbers is zero.
- Numbers with leading zeros in binary representation: A naive string-based solution may ignore leading zeros, leading to incorrect counts. The bitwise XOR method inherently handles all bits, including leading zeros, ensuring correctness.
- Maximum possible values: With numbers up to $10^9$, the XOR result can have up to 30 bits. The solution must efficiently handle counting bits without converting to strings or using large arrays. The
xor &= xor - 1technique guarantees efficiency for large inputs.