2220. Minimum Bit Flips to Convert Number
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 1
s 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
1
s, meaning 3 bits need to be flipped to convert10
to7
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 1
s 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
1
s, 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:
-
XOR Operation:
start ^ goal
- This performs a bitwise XOR between
start
andgoal
- The result is a number where each
1
bit indicates a position wherestart
andgoal
differ - Each
0
bit indicates a position where they are the same
- This performs a bitwise XOR between
-
Count the 1s:
.bit_count()
- Python's built-in
bit_count()
method counts the number of1
bits in the binary representation - This gives us the exact number of bits that need to be flipped
- Python's built-in
The algorithm works as follows:
- When we XOR two numbers, we get a binary result where:
- Bit is
1
if the corresponding bits instart
andgoal
are different - Bit is
0
if the corresponding bits instart
andgoal
are the same
- Bit is
- Since each
1
in the XOR result represents a bit that needs to be flipped, counting all the1
s 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 EvaluatorExample 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 three1
bits - Therefore, we need 3 bit flips to transform
3
into4
Verification: Let's verify by actually performing the flips on start = 3
(binary: 011
):
- Flip bit at position 0:
011
→010
(decimal: 2) - Flip bit at position 1:
010
→000
(decimal: 0) - Flip bit at position 2:
000
→100
(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.
What are the two properties the problem needs to have for dynamic programming to be applicable? (Select 2)
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!