leetcode486 (predicted winner: dynamic programming)

Given an array of non-negative integers representing scores. Player 1 takes a score from either end of the array, then player 2 continues to take the score from either end of the remaining array, and then player 1 takes,.... A player can only get one score at a time, and the score is no longer available after it is taken. The game ends when there are no points left to take. The player with the most total points wins.

Given an array of points, predict whether player 1 will be the winner. You can assume that each player's gameplay will maximize his score.

Example 1:
Input: [1, 5, 2]
Output: False

Solution (1): Recursively, record the difference between the points of the two players, and at the same time distinguish the order of the two players. When each player scores, ensure that its score is maximized.

class Solution {
    
    
     public boolean PredictTheWinner(int[] nums){
    
    
        return compare(0,nums.length-1,nums,1)>=0;
    }
     /*
      * start和end记录剩余没有被选取的数组分数段。 
      * int turn表示两个玩家的顺序,1表示第一个玩家选分,2表示第二个玩家选分
      */
    private int compare(int start,int end,int[]nums,int turn) {
    
    
          if(start==end){
    
    
              return nums[start]*turn;
          }
          int startPoint=nums[start]*turn+compare(start+1,end,nums,-turn);
          int endPoint=nums[end]*turn+compare(start,end-1,nums,-turn);
          //保证当前选分的玩家所选取的分数所选取的分数最大化
          return Math.max(startPoint*turn,endPoint*turn)*turn;
    }
}

Time complexity: O(2^n), where n is the length of the array.
Space complexity: O(n), where n is the length of the array. Space complexity depends on the stack space used by recursion

Problem solution (two): dynamic programming, set a two-dimensional array int[ ][ ]dp, dp[i][j] to represent the maximum score difference between the two players in the array segment from the i-th to the j-th number of the array.

class Solution {
    
    
    public boolean PredictTheWinner(int[] nums){
    
    
        int len=nums.length;
        int [][]dp=new int[len][len];
        for(int i=0;i<len;i++)
            dp[i][i]=nums[i];
        for(int j=1;j<len;j++)
            for(int i=0;i+j<len;i++){
    
    
                /*
                 * 得到最大的分数差。
                 * 由于当前玩家选择后,另一个玩家选择分数时时会让两人之间分数差减小,
                 * 所以是减号(nums[i]-dp[i+1][i+j]、nums[i+j]-dp[i][i+j-1])
                 */
                dp[i][i+j]=Math.max(nums[i]-dp[i+1][i+j],nums[i+j]-dp[i][i+j-1]);
            }
        return dp[0][len-1]>=0;
   }
   
}

Time complexity: O(n^2)
Space complexity: O(n)

Guess you like

Origin blog.csdn.net/CY2333333/article/details/108351933