#464
Can I Win
MediumMathDynamic ProgrammingBit ManipulationMemoizationGame TheoryBitmaskDynamic ProgrammingBit Manipulation
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n²) | O(n) |
| Space | O(1) | O(n) |
💡
Intuition
Time O(n)Space O(n)
We can use dynamic programming with memoization to avoid recalculating results for the same state. This allows us to efficiently determine if the first player can force a win by checking possible moves and their outcomes.
⚙️
Algorithm
3 steps- 1Step 1: Create a memoization table to store results for each state (used integers).
- 2Step 2: Use a recursive function to explore each possible move, checking if the opponent can win from the resulting state.
- 3Step 3: If the opponent cannot win from any of their possible moves, the first player can win from that state.
solution.py19 lines
1def canIWin(maxChoosableInteger, desiredTotal):
2 if desiredTotal <= 0:
3 return True
4 if (maxChoosableInteger * (maxChoosableInteger + 1)) // 2 < desiredTotal:
5 return False
6 memo = {}
7 def canWin(remainingTotal, used):
8 if remainingTotal <= 0:
9 return False
10 if used in memo:
11 return memo[used]
12 for i in range(1, maxChoosableInteger + 1):
13 if not (used & (1 << i)):
14 if not canWin(remainingTotal - i, used | (1 << i)):
15 memo[used] = True
16 return True
17 memo[used] = False
18 return False
19 return canWin(desiredTotal, 0)ℹ
Complexity note: The time complexity is O(n) since we are using memoization to store results for each state, significantly reducing the number of recursive calls needed.
- 1Understanding the state of the game is crucial; knowing which integers have been used helps determine possible outcomes.
- 2Optimal play means anticipating the opponent's moves and countering them effectively.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.