Min-max problem
How to tell if it’s a min-max problem:
- 2 players
- Take turns
- Both play optimally (note: optimally doesn’t mean greedy, optminally is for the final score, not current score)
- Use recursion or DP (for optimization)
Since the search space is huge O(d^b), we need to use memoization. Try to find the maximum relative score given a start position.
Time complexity: O(|problems| * |actions|)
Problems: ths start position: O(m)
Actions: take 1 or 2 or 3 stones: O(1)
Time: O(n) in total
Space: O(n) -> O(1) buttom up
877. Stone Game
Leetcode: https://leetcode.com/problems/stone-game/
Video: https://www.youtube.com/watch?v=xJ1Rc30Pyes
Similar question:
- Predict Winner: https://leetcode.com/problems/predict-the-winner/
maxDiff
returns relative score
O(2 ^ n)1
2
3
4
5
6
7
8def PredictTheWinner(self, nums: List[int]) -> bool:
def maxDiff(l, r):
if l == r:
return nums[l]
selectLeft = maxDiff(l + 1, r)
selectRight = maxDiff(l, r - 1)
return max(nums[l] - selectLeft, nums[r] - selectRight)
return maxDiff(0, len(nums) - 1) >= 0
With memoization: Use dp[l][r]
to store the best score the current player can achieve
Time: O(n^2)
Space: O(n^2)
1 | def PredictTheWinner(self, nums: List[int]) -> bool: |
DP solution
dp[i][j]
: best relative score of subarrys[i] ~ s[j]
1 | def stoneGame(self, piles: List[int]) -> bool: |
Optimize Space:
1 | def stoneGame(self, piles: List[int]) -> bool: |
1140. Stone Game II
Leetcode: https://leetcode.com/problems/stone-game-ii/
Video: https://www.youtube.com/watch?v=e_FrC5xavwI
- For the same rest of array and the same M, the result should be the same -> use memoization
- Recursion + memoization
1 | def stoneGameII(self, piles: List[int]) -> int: |
1406. Stone Game III
Leetcode: https://leetcode.com/problems/stone-game-iii/
Video: https://www.youtube.com/watch?v=uzfsrChj8dM
- Bottum up DP
dp[i]
: max relative score current player can get if the game starts at i-th stone.dp[i] = max(sum[s[i: i + k]] - dp[i + k]) while k in (1,2,3)
- Explain: if A starts at
i
, anddp[i]
is the max score A can get if A start at i, then when we move toi - 1
and let A start from there, if A pick to only have 1 step, then B would start atdp[i]
, which already saved the optminal score of the player who start atdp[i]
1 | def stoneGameIII(self, stoneValue: List[int]) -> str: |