Taro Logo

Minimum Moves to Reach Target Score

Medium
Meta logo
Meta
4 views
Topics:
Greedy AlgorithmsRecursionBit Manipulation

You are playing a game with integers. You start with the integer 1 and you want to reach the integer target.

In one move, you can either:

  1. Increment the current integer by one (i.e., x = x + 1).
  2. Double the current integer (i.e., x = 2 * x).

You can use the increment operation any number of times, however, you can only use the double operation at most maxDoubles times.

Given the two integers target and maxDoubles, return the minimum number of moves needed to reach target starting with 1.

For example:

  • target = 5, maxDoubles = 0. Output: 4. Explanation: Increment four times.
  • target = 19, maxDoubles = 2. Output: 7. Explanation: Increment to 4, double to 8, increment to 9, double to 18, increment to 19.
  • target = 10, maxDoubles = 4. Output: 4. Explanation: Increment to 2, double to 4, increment to 5, double to 10.

How would you approach this problem to find the minimum number of moves, considering the constraints on the doubling operation?

Solution


Naive Approach

The most straightforward approach is to simply increment the starting number (1) until it reaches the target. However, this would only use the increment operation and ignore the double operation. This results in target - 1 moves. This is inefficient, especially when maxDoubles is significant and target is large.

Optimal Approach

The optimal approach is to work backward from the target. If the target is even, we can halve it if we have doubles available. If the target is odd, we must decrement it by 1. We repeat this process until we reach 1. This minimizes the number of moves.

Algorithm

  1. Initialize moves = 0.
  2. While target > 1:
    • If target is even and maxDoubles > 0:
      • target = target / 2
      • maxDoubles--
      • moves++
    • Else:
      • If maxDoubles == 0: moves += target - 1; break;
      • target--
      • moves++
  3. Return moves.

Edge Cases

  • If target is 1, the number of moves is 0.
  • If maxDoubles is 0, the number of moves is target - 1.

Code (Java)

class Solution {
    public int minMoves(int target, int maxDoubles) {
        int moves = 0;
        while (target > 1) {
            if (target % 2 == 0 && maxDoubles > 0) {
                target /= 2;
                maxDoubles--;
                moves++;
            } else {
                if (maxDoubles == 0) {
                   moves += target - 1; 
                   break;
                }
                target--;
                moves++;
            }
        }
        return moves;
    }
}

Time and Space Complexity

  • Time Complexity: O(log(target)) in the best case (many doubles), O(target) in the worst case (no doubles).
  • Space Complexity: O(1) - constant extra space.