{x}
blog image

Integer Replacement

Given a positive integer n, you can apply one of the following operations:

  1. If n is even, replace n with n / 2.
  2. If n is odd, replace n with either n + 1 or n - 1.

Return the minimum number of operations needed for n to become 1.

 

Example 1:

Input: n = 8
Output: 3
Explanation: 8 -> 4 -> 2 -> 1

Example 2:

Input: n = 7
Output: 4
Explanation: 7 -> 8 -> 4 -> 2 -> 1
or 7 -> 6 -> 3 -> 2 -> 1

Example 3:

Input: n = 4
Output: 2

 

Constraints:

  • 1 <= n <= 231 - 1

Solution Explanation for Integer Replacement

The problem asks for the minimum number of operations to reduce a positive integer n to 1 using two operations: divide by 2 if even, or subtract or add 1 if odd. The optimal solution leverages a greedy approach combined with bit manipulation for efficiency.

Approach:

The core idea is to prioritize operations that lead to faster convergence to 1. Instead of blindly subtracting or adding 1 for odd numbers, we strategically choose the operation based on the number's binary representation.

  1. Even Numbers: If n is even, dividing by 2 (n >>= 1 or n /= 2) is always the optimal choice, as it directly reduces the number.

  2. Odd Numbers: This is where the strategy becomes crucial.

    • If n is odd and n-1 is divisible by 4 ((n & 3) == 3), subtracting 1 is generally beneficial. This is because subtracting 1 often results in a number divisible by 4, which can then be efficiently divided by 2 twice in subsequent steps.
    • Otherwise (for odd numbers not fulfilling the above condition), adding 1 is a reasonable choice. This is because adding 1 makes it even, which can then be divided by 2 immediately in the next step. While it might seem counterintuitive to increase the value temporarily, it often leads to a shorter path to 1.

Time and Space Complexity Analysis:

  • Time Complexity: O(log n). The algorithm's runtime is dominated by the number of iterations in the while loop. Since each operation roughly halves the value of n (or gets it close to a power of 2 that can be quickly reduced), the loop iterates approximately log₂(n) times.

  • Space Complexity: O(1). The algorithm uses only a few constant extra variables regardless of the input size, leading to constant space complexity.

Code Explanation (Python3 as an example, but the logic applies to other languages):

class Solution:
    def integerReplacement(self, n: int) -> int:
        ans = 0
        while n != 1:
            if (n & 1) == 0:  # Check if n is even
                n >>= 1       # Right bit shift (divide by 2)
            elif n != 3 and (n & 3) == 3:  # Check if odd and n-1 divisible by 4
                n += 1       # Add 1
            else:
                n -= 1       # Subtract 1
            ans += 1       # Increment operation count
        return ans

The code directly implements the strategy described above. The bitwise operations (&, >>=) are highly efficient for checking even/odd and performing division by 2. The elif condition elegantly handles the strategic decision for odd numbers.

Example Walkthrough (n = 7):

  1. n = 7 (odd, doesn't satisfy (n&3)==3), so n -= 1 (n becomes 6), ans = 1
  2. n = 6 (even), so n >>= 1 (n becomes 3), ans = 2
  3. n = 3 (odd, doesn't satisfy (n&3)==3), so n += 1 (n becomes 4), ans = 3
  4. n = 4 (even), so n >>= 1 (n becomes 2), ans = 4
  5. n = 2 (even), so n >>= 1 (n becomes 1), ans = 5
  6. Loop terminates, returning ans = 5 (This is because it shows a path that involves 5 steps)

The other language versions (Java, C++, Go) follow the same logic, with minor syntactic differences. The use of long in the C++ version is to handle potential integer overflow for very large inputs.