Guess Number Higher or Lower II — Medium Problem & Solution
A host secretly picks an integer between 1 and n. You guess repeatedly.
- Difficulty: Medium
- Topics: Math, Dynamic Programming, Game Theory
- Asked at: Amazon, Google, Microsoft
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
A host secretly picks an integer between 1 and n. You guess repeatedly. When you guess the number you win; when you guess some x that is wrong you pay x coins, and the host tells you whether the secret is higher or lower than x.
Return the smallest amount of money that guarantees a win no matter which number the host picked — that is, the cost of your best strategy against its worst-case secret.
Example 1
Input: n = 10
Output: 16
Explanation: Open with 7. If the secret is higher, guess 9 next (at most 7 + 9 = 16 paid); if lower, guess 3 and then 1 or 5 (at most 7 + 3 + 5 = 15). A last remaining number is always guessed for free, and no strategy gets by on 15.
Example 2
Input: n = 1
Output: 0
Explanation: The only possible number is guessed for free.
Example 3
Input: n = 5
Output: 6
Explanation: Guess 4; if lower, guess 2 — the worst case pays 4 + 2.
Constraints
1 <= n <= 200
How to solve Guess Number Higher or Lower II
A minimax over intervals: you choose the guess (minimise), the host chooses the side that hurts you most (maximise). Only the remaining interval matters, so memoise on (lo, hi).
Approach
dp[lo][hi] = 0whenlo >= hi(zero or one candidate left — guessing it is free).- For intervals of increasing length:
dp[lo][hi] = min over g of g + max(dp[lo][g-1], dp[g+1][hi]). - Return
dp[1][n].
Why it works
If you guess g and it is wrong you pay g and the host can steer you into whichever side is more expensive, so g + max(...) is exactly the guaranteed cost of opening with g; you then pick the best opening. Sub-intervals are independent of how you reached them, so the recurrence is exact.
Complexity
- Time —
O(n³) - Space —
O(n²)
Pitfalls
- Guessing correctly costs nothing, so a single remaining number costs 0, and two numbers
{a, a+1}costa(guess the smaller). - Binary search is not optimal: for
n = 5it would guess 3 first and pay 3 + 4 = 7 in the worst case, more than 6. - Fill the table by increasing interval length.
Reference solution
Python
def getMoneyAmount(n: int) -> int:
dp = [[0] * (n + 2) for _ in range(n + 2)]
for length in range(2, n + 1):
for lo in range(1, n - length + 2):
hi = lo + length - 1
best = 10**9
for g in range(lo, hi + 1):
left = dp[lo][g - 1]
right = dp[g + 1][hi]
cost = g + (left if left > right else right)
if cost < best:
best = cost
dp[lo][hi] = best
return dp[1][n]JavaScript
var getMoneyAmount = function(n) {
var dp = [];
for (var i = 0; i < n + 2; i++) dp.push(new Array(n + 2).fill(0));
for (var len = 2; len <= n; len++) {
for (var lo = 1; lo + len - 1 <= n; lo++) {
var hi = lo + len - 1;
var best = Infinity;
for (var g = lo; g <= hi; g++) {
var cost = g + Math.max(dp[lo][g - 1], dp[g + 1][hi]);
if (cost < best) best = cost;
}
dp[lo][hi] = best;
}
}
return dp[1][n];
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 307 math problems · the whole catalogue
Learn the technique: Dynamic Programming