Predict the Winner
Question
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.
constraints
1 <= length of the array <= 20. Any scores in the given array are non-negative integers and will not exceed 10,000,000. If the scores of both players are equal, then player 1 is still the winner.
Approach 1: 递归
为了判断哪个玩家可以获胜,需要计算一个总分,为先手得分与后手得分之差。当数组中的所有数字都被拿取时,如果总分大于或等于 0,则先手获胜,反之则后手获胜。
由于每次只能从数组的任意一端拿取数字,因此可以保证数组中剩下的部分一定是连续的。假设数组当前剩下的部分为下标
计算总分时,需要记录当前玩家是先手还是后手,判断当前玩家的得分应该记为正还是负。当数组中剩下的数字多于 1 个时,当前玩家会选择最优的方案,使得自己的分数最大化,因此对两种方案分别计算当前玩家可以得到的分数,其中的最大值为当前玩家最多可以得到的分数。
1 | class Solution(object): |
- 时间复杂度:
,其中 n 是数组的长度。 - 空间复杂度:
,其中 n 是数组的长度。空间复杂度取决于递归使用的栈空间。
Approach 2: 动态规划
方法一使用递归,存在大量重复计算,因此时间复杂度很高。由于存在重复子问题,因此可以使用动态规划降低时间复杂度。
定义二维数组
只有当
当
当
最后判断
1 | def PredictTheWinner_solution_2(self, nums): |
上述代码中使用了二维数组
1 | def PredictTheWinner_solution_2_1(self, nums): |
时间复杂度:
,其中 n 是数组的长度。需要计算每个子数组对应的 的值,共有 个子数组。 空间复杂度:
,其中 n 是数组的长度。空间复杂度取决于额外创建的数组 ,如果不优化空间,则空间复杂度是 ,使用一维数组优化之后空间复杂度可以降至 。
for 循环使用 enumerate:
1 | 'one', 'two', 'three'] seq = [ |
拓展练习
读者在做完这道题之后,可以做另一道类似的题:「877. 石子游戏」。和这道题相比,第 877 题增加了两个限制条件:
数组的长度是偶数;
数组的元素之和是奇数,所以没有平局。
对于第 877 题,除了使用这道题的解法以外,能否利用上述两个限制条件进行求解?