#464

Can I Win

Medium
MathDynamic ProgrammingBit ManipulationMemoizationGame TheoryBitmaskDynamic ProgrammingBit Manipulation
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal 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
  1. 1Step 1: Create a memoization table to store results for each state (used integers).
  2. 2Step 2: Use a recursive function to explore each possible move, checking if the opponent can win from the resulting state.
  3. 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.