Guess Number Higher or Lower II

MEDIUM

Description

We are playing the Guessing Game. The game will work as follows:

  1. I pick a number between 1 and n.
  2. You guess a number.
  3. If you guess the right number, you win the game.
  4. If you guess the wrong number, then I will tell you whether the number I picked is higher or lower, and you will continue guessing.
  5. Every time you guess a wrong number x, you will pay x dollars. If you run out of money, you lose the game.

Given a particular n, return the minimum amount of money you need to guarantee a win regardless of what number I pick.

 

Example 1:

Input: n = 10
Output: 16
Explanation: The winning strategy is as follows:
- The range is [1,10]. Guess 7.
    - If this is my number, your total is $0. Otherwise, you pay $7.
    - If my number is higher, the range is [8,10]. Guess 9.
        - If this is my number, your total is $7. Otherwise, you pay $9.
        - If my number is higher, it must be 10. Guess 10. Your total is $7 + $9 = $16.
        - If my number is lower, it must be 8. Guess 8. Your total is $7 + $9 = $16.
    - If my number is lower, the range is [1,6]. Guess 3.
        - If this is my number, your total is $7. Otherwise, you pay $3.
        - If my number is higher, the range is [4,6]. Guess 5.
            - If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $5.
            - If my number is higher, it must be 6. Guess 6. Your total is $7 + $3 + $5 = $15.
            - If my number is lower, it must be 4. Guess 4. Your total is $7 + $3 + $5 = $15.
        - If my number is lower, the range is [1,2]. Guess 1.
            - If this is my number, your total is $7 + $3 = $10. Otherwise, you pay $1.
            - If my number is higher, it must be 2. Guess 2. Your total is $7 + $3 + $1 = $11.
The worst case in all these scenarios is that you pay $16. Hence, you only need $16 to guarantee a win.

Example 2:

Input: n = 1
Output: 0
Explanation: There is only one possible number, so you can guess 1 and not have to pay anything.

Example 3:

Input: n = 2
Output: 1
Explanation: There are two possible numbers, 1 and 2.
- Guess 1.
    - If this is my number, your total is $0. Otherwise, you pay $1.
    - If my number is higher, it must be 2. Guess 2. Your total is $1.
The worst case is that you pay $1.

 

Constraints:

  • 1 <= n <= 200

Approaches

Checkout 3 different approaches to solve Guess Number Higher or Lower II. Click on different approaches to view the approach and algorithm in detail.

Bottom-Up Dynamic Programming (Tabulation)

This approach solves the problem iteratively using bottom-up dynamic programming, also known as tabulation. It avoids recursion and its associated overhead, often leading to better performance. We use a 2D table, dp[i][j], to store the minimum cost to guarantee a win for the number range [i, j]. The key idea is to fill this table by starting with the smallest subproblems (ranges of length 2) and progressively building up to the solution for the full range [1, n]. By iterating through range lengths, we ensure that when we calculate dp[i][j], the solutions for all smaller, required subproblems (like dp[i][k-1] and dp[k+1][j]) have already been computed and stored in the table.

Algorithm

  1. Create a 2D DP table dp of size (n+2) x (n+2) and initialize all its values to 0. The extra padding helps handle boundary cases like k-1 and k+1 without extra checks.
  2. Iterate over the length of the range, len, from 2 to n.
  3. Inside this loop, iterate over all possible starting points i for a range of length len. The loop for i will go from 1 up to n - len + 1.
  4. Calculate the end point of the current range: j = i + len - 1.
  5. For the current range [i, j], initialize its cost dp[i][j] to Integer.MAX_VALUE.
  6. Iterate through all possible first guesses k from i to j.
  7. For each guess k, calculate the cost using the already computed values from smaller sub-ranges: cost = k + max(dp[i][k-1], dp[k+1][j]).
  8. Update the minimum cost for the range [i, j]: dp[i][j] = min(dp[i][j], cost).
  9. After all loops complete, the value dp[1][n] will contain the minimum cost to guarantee a win for the entire range [1, n]. Return this value.

Instead of starting from the top problem (1, n) and breaking it down, the bottom-up approach starts with the smallest problems and builds up. We use a 2D array dp[n+2][n+2] where dp[i][j] stores the solution for the subproblem on the range [i, j]. The base cases are ranges of length 0 or 1, for which the cost is 0. Our DP table is initialized to 0, which covers these cases. We then iterate on the length of the range, len, from 2 to n. For each len, we iterate through all possible start indices i. The end index j is simply i + len - 1. For each range [i, j], we calculate dp[i][j] by trying every possible split point k (our first guess) from i to j. The cost for guessing k is k + max(dp[i][k-1], dp[k+1][j]). Since we are iterating by increasing length, the values dp[i][k-1] (for range length k-i) and dp[k+1][j] (for range length j-k) are guaranteed to have been computed in previous iterations. We take the minimum cost over all possible k. The final answer is the value stored in dp[1][n].

public class Solution {
    public int getMoneyAmount(int n) {
        if (n == 1) {
            return 0;
        }
        // dp[i][j] = min cost for range [i, j]
        int[][] dp = new int[n + 2][n + 2];

        for (int len = 2; len <= n; len++) {
            for (int i = 1; i <= n - len + 1; i++) {
                int j = i + len - 1;
                dp[i][j] = Integer.MAX_VALUE;
                for (int k = i; k <= j; k++) {
                    int cost = k + Math.max(dp[i][k - 1], dp[k + 1][j]);
                    dp[i][j] = Math.min(dp[i][j], cost);
                }
            }
        }

        return dp[1][n];
    }
}

Complexity Analysis

Time Complexity: O(n^3). The three nested loops for `len`, `i`, and `k` dominate the runtime. `len` runs up to `n`, `i` runs up to `n`, and `k` runs up to `n` times in the worst case.Space Complexity: O(n^2), for the 2D DP table.

Pros and Cons

Pros:
  • Generally the most efficient solution for the given constraints due to the absence of recursion overhead.
  • Iterative nature can make it easier to analyze and debug.
  • Guarantees the optimal solution.
Cons:
  • Can be slightly less intuitive to formulate than the recursive top-down approach.
  • Still has a cubic time complexity, which might be too slow for much larger constraints.

Code Solutions

Checking out 3 solutions in different languages for Guess Number Higher or Lower II. Click on different languages to view the code.


Video Solution

Watch the video walkthrough for Guess Number Higher or Lower II



Patterns:

MathDynamic ProgrammingGame Theory

Subscribe to Scale Engineer newsletter

Learn about System Design, Software Engineering, and interview experiences every week.

No spam, unsubscribe at any time.