Skip to content

Commit 4ea7ace

Browse files
Merge pull request #254 from ravi0213/issue-250
[ISSUE-250]add a solution for Predict the winner problem
2 parents 8d20bb1 + b1b1d8a commit 4ea7ace

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

LeetCode/PredictTheWinner.java

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import java.io.BufferedReader;
2+
import java.io.IOException;
3+
import java.io.InputStreamReader;
4+
import java.util.Arrays;
5+
6+
/*
7+
* Problem:
8+
* Given an array of integers of size `n`. Now 2 players are playing a game with this array.
9+
* They make their turn alternatively and in each turn, they pick a number from either end and add it to their score.
10+
* If player 1 gets more or equal score than the player 2, player 1 wins otherwise player 2 wins.
11+
* Both players play the game optimally.
12+
*
13+
* Approach: Dynamic Programming
14+
* As we know both players play optimally,
15+
* If a player pick an element from either end then next player will also try to maximize the score and will try to minimize other player's score
16+
* So for subarray `i` and `j`, the recurrence would be,
17+
* dp[i][j] = Math.max(
18+
* a[i] + Math.min(dp[i + 1][j - 1], dp[i + 2][j]),
19+
* a[j] + Math.min(dp[i + 1][j - 1], dp[i][j - 2])
20+
* )
21+
* and base case would be dp[i][i] = a[i]
22+
* Complexity:
23+
* Time complexity = O(n * n) // as we have 2 dp states, the complexity is squared
24+
* Space complexity = O(n * n) // as we are calculating an answer for each subarray, the complexity is also squared
25+
*/
26+
27+
public class PredictTheWinner {
28+
private static boolean PredictTheWinner(int[] nums) {
29+
int totalScore = 0;
30+
31+
// iterate through all the elements in an array to calculate the total possible score
32+
for(int i = 0; i < nums.length; i++) {
33+
totalScore += nums[i];
34+
}
35+
36+
// initialize a 2-d dp array to store answers for sub problems
37+
// if the dp[i][j] is -1, that means we haven't calculated the answer for that particular subarray
38+
// if not, then we can simply return the value instead of recalculating it again
39+
int[][] dp = new int[nums.length][nums.length];
40+
for(int i = 0; i < nums.length; i++) {
41+
for(int j = 0; j < nums.length; j++ ) {
42+
dp[i][j] = -1;
43+
}
44+
}
45+
46+
// let's find out what is maximum score player 1 can get if plays optimally
47+
int player1Score = score(nums, 0, nums.length - 1, dp);
48+
49+
// similarly we can simply subtract it from total possible score to calculate the player 2 score
50+
int player2Score = totalScore - player1Score;
51+
52+
// player 1 wins if the score is not lower than player 2 score
53+
return player1Score >= player2Score;
54+
}
55+
56+
private static int score(int[] nums, int i, int j, int[][] dp) {
57+
if(i > j) return 0;
58+
59+
// this is the base case and for single element, nums[i] is the only possible score a player can get
60+
if(i == j) return nums[i];
61+
62+
// if we have already calculated the score for this subarray, then we don't need to recalculate it
63+
// and can return the one we stored in the 2d dp array
64+
if(dp[i][j] != -1) return dp[i][j];
65+
66+
// here a player can have two choice,
67+
// 1) player picks the number from left end
68+
// 2) or player picks the number from right end
69+
// check above for the detailed explaination about the recurrence
70+
int selectLeft = nums[i] + Math.min(
71+
score(nums, i + 2, j, dp),
72+
score(nums, i + 1, j - 1, dp)
73+
);
74+
75+
int selectRight = nums[j] + Math.min(
76+
score(nums, i, j - 2, dp),
77+
score(nums, i + 1, j - 1, dp)
78+
);
79+
80+
// persist the optimal score in an dp array before returning it
81+
return dp[i][j] = Math.max(selectLeft, selectRight);
82+
}
83+
84+
public static void main(String[] args) throws IOException {
85+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
86+
int n = Integer.parseInt(br.readLine());
87+
88+
int[] array = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
89+
90+
System.out.println(PredictTheWinner(array));
91+
}
92+
}

0 commit comments

Comments
 (0)