Predict the Winner LT486
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 <= 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.
Idea 1.a backtracking with memory. For the first player to win, the score score1 >= score2 for the second player, while score1 + score2 = sum of all scores in the array, it mean score1 * 2 >= sum. Let dp(a, b) represent the maxmum score of player1 when choosing in the range nums[a, b], based on the observation and -max(-a, -b) = min(a, b), we can get the followig equation:
dp(a, b) = max(sum(a, b) - dp(a+1, b), sum(a, b) - dp(a, b-1))
= max(nums[a] - max(-dp(a+2, b), -dp(a+1, b-1),
nums[b] - max(-dp(a+1, b-1), -dp(a, b-2)))
= max(nums[a] + min(dp(a+2, b), dp(a+1, b-1)),
nums[b] + min(dp(a+1, b-1), dp(a, b-2)))
Time complexity: O(n2)
Space complexity: O(n2)
class Solution {
private int maxScoreForRange(int[] nums, int a, int b, int[][] maxScores) {
if(a > b) {
return 0;
} if(maxScores[a][b] == 0) {
int scoreA = nums[a] + Math.min(maxScoreForRange(nums, a+2, b, maxScores), maxScoreForRange(nums, a+1, b-1, maxScores));
int scoreB = nums[b] + Math.min(maxScoreForRange(nums, a+1, b-1, maxScores), maxScoreForRange(nums, a, b-2, maxScores));
maxScores[a][b] = Math.max(scoreA, scoreB);
} return maxScores[a][b];
} public boolean PredictTheWinner(int[] nums) {
int sum = 0;
for(int num: nums) {
sum += num;
} int[][] maxScores = new int[nums.length][nums.length];
if(maxScoreForRange(nums, 0, nums.length-1, maxScores) * 2 >= sum) {
return true;
}
return false;
}
}
Idea 1.b, recursion, based on the idea that score1 >= score2, score1 - score2 >= 0, avoid the computation to calculate the sum. We use turn to represent player1 (turn =1 ) and player2(turn = -1), and switch turn based on the player.
Note: the returned value is given by turn * max(turn*b, turn *b), equivalently max(a, b) for player1's turn and min(a, b) for player2's turn.
Time complexity: O(2^n), size of recursion tree is 2^n
Space complexity: O(n) the depth of the recursion tree
class Solution {
private int differenceForRange(int[] nums, int a, int b, int turn) {
if(a > b) {
return 0;
} int scoreA = turn * nums[a] + differenceForRange(nums, a+1, b, -turn);
int scoreB = turn * nums[b] + differenceForRange(nums, a, b-1, -turn); return turn * Math.max(turn * scoreA, turn * scoreB);
} public boolean PredictTheWinner(int[] nums) { if(differenceForRange(nums, 0, nums.length-1, 1) >= 0) {
return true;
}
return false;
}
}
with variable turn, add the choice when it's player1's turn, subtract the choice when it's player2's turn.
Time complexity: O(2^n)
Space complexity: O(n)
class Solution {
private int differenceForRange(int[] nums, int a, int b) {
if(a > b) {
return 0;
} int scoreA = nums[a] - differenceForRange(nums, a+1, b);
int scoreB = nums[b] - differenceForRange(nums, a, b-1); return Math.max(scoreA, scoreB);
} public boolean PredictTheWinner(int[] nums) {
return differenceForRange(nums, 0, nums.length-1) >= 0;
}
}
Idea 1.c recusion + memory
Time complexity: O(n2)
Space complexity: O(n2)
class Solution {
private int differenceForRange(int[] nums, int a, int b, Integer[][] diffScores) {
if(a > b) {
return 0;
} if(diffScores[a][b] == null) {
int scoreA = nums[a] - differenceForRange(nums, a+1, b, diffScores);
int scoreB = nums[b] - differenceForRange(nums, a, b-1, diffScores); diffScores[a][b] = Math.max(scoreA, scoreB);
} return diffScores[a][b];
} public boolean PredictTheWinner(int[] nums, Integer[][] diffScores) {
Integer[][] diffScores = new Integer[nums.length][nums.length];
return differenceForRange(nums, 0, nums.length-1, diffScores) >= 0;
}
}
Idea 2. Dynamic programming based on the equation about diffence on score:
dp(a, b) = Math.max(nums[a] - dp(a+1, b), nums[b] - dp(a, b-1))
class Solution {
public boolean PredictTheWinner(int[] nums) {
int[][] scores = new int[nums.length][nums.length]; for(int i = nums.length-1; i >= 0; --i) {
scores[i][i] = nums[i];
for(int len = 2; i + len - 1 < nums.length; ++len) {
int j = i + len - 1;
scores[i][j] = Math.max(nums[i] - scores[i+1][j],
nums[j] - scores[i][j-1]);
}
}
return scores[0][nums.length-1] >= 0;
}
}
Time complexity: O(n2)
Space complexity: O(n2)
Idea 3. Based on the above equation, we can use row instead of matrix by updating from left to right as previous value on the same row is needed and down to up as traversing the hidden matrix via a row.
row(b) = max(nums[a] - row(b_old), nums[b] - row[b-1])
Time complexity: O(n2)
Space complexity: O(n)
class Solution {
public boolean PredictTheWinner(int[] nums) {
int[] row = new int[nums.length]; for(int i = nums.length-1; i >= 0; --i) {
row[i] = nums[i];
for(int len = 2; i + len - 1 < nums.length; ++len) {
int j = i + len - 1;
row[j] = Math.max(nums[i] - row[j],
nums[j] - row[j-1]);
}
}
return row[nums.length-1] >= 0;
}
}
python:
class Solution:
def DiffScoresForRange(self, nums: List[int], a: int, b: int, diffScores) -> int:
if a > b:
return 0 if diffScores[a][b] == None :
scoreA = nums[a] - self.DiffScoresForRange(nums, a+1, b, diffScores)
scoreB = nums[b] - self.DiffScoresForRange(nums, a, b-1, diffScores)
diffScores[a][b] = max(scoreA, scoreB) return diffScores[a][b] def PredictTheWinner(self, nums: List[int]) -> bool:
diffScores = [[None for j in range(len(nums))] for i in range(len(nums))]
return self.DiffScoresForRange(nums, 0, len(nums)-1, diffScores) >= 0
class Solution:
def PredictTheWinner(self, nums: List[int]) -> bool:
diffScores = [[0 for j in range(len(nums))] for i in range(len(nums))] for i in range(len(nums)-1, -1, -1):
diffScores[i][i] = nums[i]
for length in range(2, len(nums)+1-i, 1):
j = i + length - 1
diffScores[i][j] = max(nums[i] - diffScores[i+1][j],
nums[j] - diffScores[i][j-1]) return diffScores[0][len(nums)-1] >= 0
class Solution:
def PredictTheWinner(self, nums: List[int]) -> bool:
row = [0 for i in range(len(nums))] for i in range(len(nums)-1, -1, -1):
row[i] = nums[i]
for length in range(2, len(nums)+1-i, 1):
j = i + length - 1
row[j] = max(nums[i] - row[j],
nums[j] - row[j-1]) return row[len(nums)-1] >= 0
Predict the Winner LT486的更多相关文章
- LN : leetcode 486 Predict the Winner
lc 486 Predict the Winner 486 Predict the Winner Given an array of scores that are non-negative inte ...
- LC 486. Predict the Winner
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
- Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)
Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端 ...
- 【LeetCode】486. Predict the Winner 解题报告(Python)
[LeetCode]486. Predict the Winner 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...
- [LeetCode] Predict the Winner 预测赢家
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
- [Swift]LeetCode486. 预测赢家 | Predict the Winner
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
- Minimax-486. Predict the Winner
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
- 动态规划-Predict the Winner
2018-04-22 19:19:47 问题描述: Given an array of scores that are non-negative integers. Player 1 picks on ...
- 486. Predict the Winner
Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...
随机推荐
- Java冒泡具体的原理,以及下标的变化
原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将 ...
- yum update 自动忽略内核更新
系统每天凌晨 3 点自动执行 yum update 任务 但升级内核后,会出现下面情况 一些编译软件需要内核模块才能够被调用, 而内核模块需要与当前版本内核编译后才能够使用, 假设内核升级后,之前软件 ...
- php递归获取目录下所有文件
<?php function getFileList($dir){ $dir=iconv("utf-8","gb2312",$dir); if ($hea ...
- Centos 7 下 Mysql 5.7 Galera Cluster 集群部署
一.介绍 传统架构的使用,一直被人们所诟病,因为MySQL的主从模式,天生的不能完全保证数据一致,很多大公司会花很大人力物力去解决这个问题,而效果却一般,可以说,只能是通过牺牲性能,来获得数据一致性 ...
- 100-days: Seven
Title: Can baiju, China's sorghum firewater, go global? sorghum n. 高粱 firewater n. 烈酒 Baijiu——a broa ...
- EasyUI Dialog 对话框 关闭事件
在 $('#×××').dialog('close'); 执行后触发 $(function(){ $("#titledialos").dialog({ onClose: fun ...
- 662. Maximum Width of Binary Tree二叉树的最大宽度
[抄题]: Given a binary tree, write a function to get the maximum width of the given tree. The width of ...
- 11-web网页制作APP
如何将H5和WebApp 加壳成apk.ipa 问题:已经做好的纯H5的站点 想分别加两个壳子,变成apk和ipa ,要怎么实现? 要点: 1. app只是壳子,打开app直接跳转到H5的Ur ...
- 34-BigInteger详解
在用C或者C++处理大数时感觉非常麻烦,但是在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,至于两个类的对象能表示最大范围不清楚,理论上能够表示无线大的数, ...
- pthreads v3下的Volatile介绍与使用
由于pthreads v3中引入了Threaded对象自动不变性的概念,所以当我们在构造函数中给成员设置为数组时,在其他地方就无法对成员再次改写了. 例子如下: <?php //pthreads ...