|
| 1 | +package dynamic_programming; |
| 2 | + |
| 3 | +/** |
| 4 | + * Description: https://leetcode.com/problems/predict-the-winner |
| 5 | + * Difficulty: Medium |
| 6 | + * Time complexity: O(n^2) |
| 7 | + * Space complexity: O(n^2) |
| 8 | + */ |
| 9 | +public class PredictWinner { |
| 10 | + |
| 11 | + private static final int FIRST_PLAYER = 0; |
| 12 | + private static final int SECOND_PLAYER = 1; |
| 13 | + |
| 14 | + public boolean predictTheWinner(int[] nums) { |
| 15 | + // we track FIRST_PLAYER's score as positive and SECOND_PLAYER's as negative |
| 16 | + // if total score is greater or equal than 0 -> FIRST_PLAYER wins |
| 17 | + return play(nums, 0, nums.length - 1, FIRST_PLAYER, new int[nums.length][nums.length]) >= 0; |
| 18 | + } |
| 19 | + |
| 20 | + private int play(int[] nums, int left, int right, int player, int[][] memo) { |
| 21 | + if (left > right) return 0; |
| 22 | + if (memo[left][right] != 0) return memo[left][right]; |
| 23 | + |
| 24 | + if (player == FIRST_PLAYER) { |
| 25 | + int takeLeft = nums[left] + play(nums, left + 1, right, SECOND_PLAYER, memo); |
| 26 | + int takeRight = nums[right] + play(nums, left, right - 1, SECOND_PLAYER, memo); |
| 27 | + memo[left][right] = Math.max(takeLeft, takeRight); |
| 28 | + } else { |
| 29 | + int takeLeft = -nums[left] + play(nums, left + 1, right, FIRST_PLAYER, memo); |
| 30 | + int takeRight = -nums[right] + play(nums, left, right - 1, FIRST_PLAYER, memo); |
| 31 | + memo[left][right] = Math.min(takeLeft, takeRight); |
| 32 | + } |
| 33 | + |
| 34 | + return memo[left][right]; |
| 35 | + } |
| 36 | +} |
0 commit comments