You are given two integers maxChoosableInteger and desiredTotal. You can only choose an integer from 1 to maxChoosableInteger each time. Each integer can only be chosen once. The player who makes the total sum reach or exceed the desiredTotal first is the winner.
Assume that both players play optimally. Return true if the first player to move can force a win, otherwise return false.
maxChoosableInteger and desiredTotal?
1 <= maxChoosableInteger <= 200 <= desiredTotal <= 300desiredTotal be zero?
desiredTotal is zero, the first player automatically loses because they cannot make a move and hence cannot win.maxChoosableInteger will be enough to reach the desiredTotal?
1 + 2 + ... + maxChoosableInteger is less than desiredTotal, it’s impossible for any player to win.desiredTotal is 0 the first player loses by definition since no moves lead to a win.1 to maxChoosableInteger is less than desiredTotal, then it’s impossible for any player to reach the desiredTotal. Return false in this case.import java.util.HashMap;
import java.util.Map;
public class Solution {
public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
int sum = (maxChoosableInteger * (maxChoosableInteger + 1)) / 2;
// If the sum of all available numbers is less than the desiredTotal, there's no way to reach the target
if (sum < desiredTotal) {
return false;
}
// Use memoization to remember previously computed states
Map<Integer, Boolean> memo = new HashMap<>();
return canIWinHelper(maxChoosableInteger, desiredTotal, 0, memo);
}
private boolean canIWinHelper(int maxChoosableInteger, int total, int usedNumbers, Map<Integer, Boolean> memo) {
if (total <= 0) {
return false;
}
if (memo.containsKey(usedNumbers)) {
return memo.get(usedNumbers);
}
for (int i = 1; i <= maxChoosableInteger; i++) {
int currentMask = (1 << i);
// If the number i is already used, continue
if ((usedNumbers & currentMask) != 0) {
continue;
}
// If choosing i wins the game, or forces the opponent to lose on their turn
if (total - i <= 0 || !canIWinHelper(maxChoosableInteger, total - i, usedNumbers | currentMask, memo)) {
memo.put(usedNumbers, true);
return true;
}
}
memo.put(usedNumbers, false);
return false;
}
}
maxChoosableInteger.O(2^N * N) where N is maxChoosableInteger because there are 2^N possible combinations of states and for each state, we may check up to N possibilities.Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?