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.

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的更多相关文章

  1. 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 ...

  2. LC 486. Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  3. Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)

    Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端 ...

  4. 【LeetCode】486. Predict the Winner 解题报告(Python)

    [LeetCode]486. Predict the Winner 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  5. [LeetCode] Predict the Winner 预测赢家

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  6. [Swift]LeetCode486. 预测赢家 | Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  7. Minimax-486. Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  8. 动态规划-Predict the Winner

    2018-04-22 19:19:47 问题描述: Given an array of scores that are non-negative integers. Player 1 picks on ...

  9. 486. Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

随机推荐

  1. 2.4、CDH 搭建Hadoop在安装(Cloudera Software安装和配置MySQL)

    为Cloudera Software安装和配置MySQL 要使用MySQL数据库,请按照以下过程操作.有关MySQL数据库兼容版本的信息,请参阅CDH和Cloudera Manager支持的数据库. ...

  2. python网络编程之C/S架构介绍

    标签(空格分隔): c/s架构介绍 什么是C/S架构 C指的是client(客户端软件),S指的是Server(服务端软件),后续我们可以试着写个c/s软件实现服务器软件与客户端软件基于网络通信: 计 ...

  3. (django1.10)访问url报错Forbidden (CSRF cookie not set.): xxx

    问题:页面访问时报错 Forbidden (CSRF cookie not set.): xxx     解决方法: 修改settings.py文件,注释掉 django.middleware.csr ...

  4. contextlib 上下文管理器

    在Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们.正确关闭文件资源的一个方法是使用try...finally: try: f = open('/path/to/file', ...

  5. 关于cdh 5.X 的agent 客户端镜像安装注意事项

    当把客户端镜像安装时,每个客户端程序会生成UUID作为唯一标识,重新 安装时要删除 rm -rf /var/lib/cloudera-scm-agent 如果不删除会造成主机列表中IP一直在变的情况.

  6. Ant 初级入门

    一.Ant简介 Ant是一个Apache基金会下的跨平台的构件工具. 由于Ant是基于Java的,所以需要Java环境的支持,也就是配置好 JAVA_HOME 和 ANT_HOME 环境变量分别指向J ...

  7. TOJ 3973 Maze Again && TOJ 3128 简单版贪吃蛇

    TOJ3973传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3973 时间限制(普通 ...

  8. uniquefu Python+Selenium学习--select

    场景 在处理下拉框(select)的时候selenium给我们提供了一系列的便捷方法,我们只需要使用selenium.webdriver.support.select.Select类来稍微封装一下就好 ...

  9. Matches Game

    Matches Game http://poj.org/problem?id=2234 Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  10. iOS 证书申请新步骤

    2018iOS完整的证书申请和打包过程 - 简书https://www.jianshu.com/p/2b3c2693f4f2