zoukankan      html  css  js  c++  java
  • 486. Predict the Winner

    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:

    1. 1 <= length of the array <= 20.
    2. Any scores in the given array are non-negative integers and will not exceed 10,000,000.
    3. If the scores of both players are equal, then player 1 is still the winner.

    题目含义:给定一个正整数数组,选手1从数组的头部或者尾部选择一个数,选手2从剩下部分的头部或尾部选择一个数,循环往复,直到该数组中的数都被取完。判断选手1取的数的和值是否大于选手2.

    思路:

    两人依次拿,如果Player1赢,则Player1拿的>Player2拿的。我们把Player1拿的视为"+",把Player2拿的视为"-",如果最后结果大于等于0则Player1赢。

    该问题没有直接比较一个选手所拿元素的和值,而是把问题转换为两个选手所拿元素的差值。这一点很巧妙,是关键的一步。

    因此对于递归来说,beg ~ end的结果为max(nums[beg] - partition(beg + 1, end), nums[end] - partition(beg, end - 1));

    方法一:递归解法

    1     public boolean PredictTheWinner(int[] nums) {
    2         return helper(nums, 0, nums.length-1) >= 0;
    3     }
    4     
    5     public int helper(int[] nums, int start, int end) {
    6         if(start == end) return nums[start];
    7         else return Math.max(nums[start]-helper(nums, start+1,end), nums[end]-helper(nums, start,end-1));
    8     }

    方法二:dp解法

    对于非递归算法,首先在dp中赋初始值,这是我们解题的第一步。在这个问题中,对于非递归来说DP[beg][end]表示即为beg ~ end所取的值的大小(最终与零比较)。我们使用一个二位的数组dp来表示nums数组中任意开始和结束位置两人结果的差值。

    初始的时候,我们仅仅知道对角线上的值。dp[i][i] = nums[i]. 这一点很好理解。

    接下来既然是求任意的开始和结束,对于二维数组,那肯定是一个双层的循环。通过dp中已知的元素和动态规划的递推表达式,我们就可以构造出我们的需要的结果。非递归的方式是从小问题到大问题的过程。

     1     public boolean PredictTheWinner(int[] nums) {
     5         if(nums == null || nums.length == 0) return false;
     6         int n = nums.length;
     7         int[][] dp = new int[n][n];
     8 
     9         for(int i = 0; i < n; i++) {
    10             dp[i][i] = nums[i];
    11         }
    12 
    13         for(int i = n-2; i >= 0; i--) {
    14             for(int j = i+1; j < n; j++) {
    15                 dp[i][j] = Math.max(nums[i]-dp[i+1][j], nums[j]-dp[i][j-1]);
    16             }
    17         }
    18         return dp[0][n-1] >= 0;
    19     }
  • 相关阅读:
    怎样使用Secure CRT查看vcenter和esxi主机的日志文件(转)
    Linux下如何查看系统启动时间和运行时间
    Java使用线程并发库模拟弹夹装弹以及发射子弹的过程
    使用Java线程并发库实现两个线程交替打印的线程题
    Android Exception Type "share_dialog_title" is not translated in en, zh-rTW strings
    Java JDK1.5、1.6、1.7新特性整理
    Java 中long类型转换成为int类型时可能会出错的地方
    Java 将任意数组的任意两个位置的数据进行交换
    Java设置以及获取JavaBean私有属性进阶
    Java使用PropertyDescriptor获取实体类中私有属性的值,并给私有属性赋值
  • 原文地址:https://www.cnblogs.com/wzj4858/p/7698231.html
Copyright © 2011-2022 走看看