Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins.
Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score.
Example 1:
Input: [1, 5, 2] Output: False Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return False.
Example 2:
Input: [1, 5, 233, 7] Output: True Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.
Note:
The idea behind the recursive approach is simple. The two players Player 1 and Player 2 will be taking turns alternately. For the Player 1 to be the winner, we need . Or in other terms, .
\nThus, for the turn of Player 1, we can add its score obtained to the total score and for Player 2\'s turn, we can substract its score from the total score. At the end, we can check if the total score is greater than or equal to zero(equal score of both players), to predict that Player 1 will be the winner.
\nThus, by making use of a recursive function winner(nums,s,e,turn)
which predicts the winner for the array as the score array with the elements in the range of indices currently being considered, given a particular player\'s turn, indicated by being Player 1\'s turn and being the Player 2\'s turn, we can predict the winner of the given problem by making the function call winner(nums,0,n-1,1)
. Here, refers to the length of array.
In every turn, we can either pick up the first() or the last() element of the current subarray. Since both the players are assumed to be playing smartly and making the best move at every step, both will tend to maximize their scores. Thus, we can make use of the same function winner
to determine the maximum score possible for any of the players.
Now, at every step of the recursive process, we determine the maximum score possible for the current player. It will be the maximum one possible out of the scores obtained by picking the first or the last element of the current subarray.
\nTo obtain the score possible from the remaining subarray, we can again make use of the same winner
function and add the score corresponding to the point picked in the current function call. But, we need to take care of whether to add or subtract this score to the total score available. If it is Player 1\'s turn, we add the current number\'s score to the total score, otherwise, we need to subtract the same.
Thus, at every step, we need update the search space appropriately based on the element chosen and also invert the \'s value to indicate the turn change among the players and either add or subtract the current player\'s score from the total score available to determine the end result.
\nFurther, note that the value returned at every step is given by . This is equivalent to the statement for Player 1\'s turn and for Player 2\'s turn.
\nThis is done because, looking from Player 1\'s perspective, for any move made by Player 1, it tends to leave the remaining subarray in a situation which minimizes the best score possible for Player 2, even if it plays in the best possible manner. But, when the turn passes to Player 1 again, for Player 1 to win, the remaining subarray should be left in a state such that the score obtained from this subarrray is maximum(for Player 1).
\nThis is a general criteria for any arbitrary two player game and is commonly known as the \nMin-Max algorithm.
\nThe following image shows how the scores are passed to determine the end result for a simple example.
\nComplexity Analysis
\nTime complexity : . Size of recursion tree will be . Here, refers to the length of array.
\nSpace complexity : . The depth of the recursion tree can go upto .
\nAlgorithm
\nWe can omit the use of to keep a track of the player for the current turn. To do so, we can make use of a simple observation. If the current turn belongs to, say Player 1, we pick up an element, say , from either end, and give the turn to Player 2. Thus, if we obtain the score for the remaining elements(leaving ), this score, now belongs to Player 2. Thus, since Player 2 is competing against Player 1, this score should be subtracted from Player 1\'s current(local) score() to obtain the effective score of Player 1 at the current instant.
\nSimilar argument holds true for Player 2\'s turn as well i.e. we can subtract Player 1\'s score for the remaining subarray from Player 2\'s current score to obtain its effective score. By making use of this observation, we can omit the use of from winner
to find the required result by making the slight change discussed above in the winner
\'s implementation.
While returning the result from winner
for the current function call, we return the larger of the effective scores possible by choosing either the first or the last element from the currently available subarray. Rest of the process remains the same as the last approach.
Now, in order to remove the duplicate function calls, we can make use of a 2-D memoization array, , such that we can store the result obtained for the function call winner
for a subarray with starting and ending indices being and ] at . This helps to prune the search space to a great extent.
This approach is inspired by @chidong
\n\nComplexity Analysis
\nTime complexity : . The entire array of size x is filled only once. Here, refers to the size of array.
\nSpace complexity : . array of size x is used for memoization.
\nAlgorithm
\nWe can observe that the effective score for the current player for any given subarray only depends on the elements within the range in the array . It mainly depends on whether the element or is chosen in the current turn and also on the maximum score possible for the other player from the remaining subarray left after choosing the current element. Thus, it is certain that the current effective score isn\'t dependent on the elements outside the range .
\nBased on the above observation, we can say that if know the maximum effective score possible for the subarray and , we can easily determine the maximum effective score possible for the subarray as . These equations are deduced based on the last approach.
\nFrom this, we conclude that we can make use of Dynamic Programming to determine the required maximum effective score for the array . We can make use of a 2-D array, such that is used to store the maximum effective score possible for the subarray . The updation equation becomes:
\n\n.
\nWe can fill in the array starting from the last row. At the end, the value for gives the required result. Here, refers to the length of array.
\nLook at the animation below to clearly understand the filling process.
\n!?!../Documents/486_Predict_the_winner.json:1000,563!?!
\n\nComplexity Analysis
\nTime complexity : . x entries in array of size x is filled once. Here, refers to the length of array.
\nSpace complexity : . array of size x is used.
\nAlgorithm
\nFrom the last approach, we see that the updation equation is:
\n\n.
\nThus, for filling in any entry in array, only the entries in the next row(same column) and the previous column(same row) are needed.
\nInstead of making use of a new row in array for the current row\'s updations, we can overwrite the values in the previous row itself and consider the values as belonging to the new row\'s entries, since the older values won\'t be needed ever in the future again. Thus, instead of making use of a 2-D array, we can make use of a 1-D array and make the updations appropriately.
\n\nComplexity Analysis
\nTime complexity : . The elements of array are updated times. Here, refers to the length of array.
\nSpace complexity : . 1-D array of size is used.
\nAnalysis written by: @vinod23
\n