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. Spring beanFactory ApplicationContext

    一.BeanFactoryBeanFactory 是 Spring 的“心脏”.它就是 Spring IoC 容器的真面目.Spring 使用 BeanFactory 来实例化.配置和管理 Bean. ...

  2. python文件操作 二

    问题:在传输的时候对方不知道是以什么格式传给用户,传来传去彼此都忘了什么格式: 在编码的时候:utf8:是3个字符,gbk是2个字符,每个字符数字对应的字符,一段2进制串,如果10个字节全部都是中文, ...

  3. EHR ORA--1187由于验主频雘失败而无法从文件读取 ORA-01110数据文件temp01.dbf

    alter tablespace TEMP add tempfile '/data/oracle/oradata/orcl/temp02.dbf' size 100m autoextend on; a ...

  4. asp.net之发送邮件1

    /// <summary> ///发邮件给用户 /// </summary> /// <param name="userEmail">用户的邮件 ...

  5. sqlserver 当前时间减去30天

    参考 https://zhidao.baidu.com/question/750666819064717772.html select dateadd(dd,-30,getdate()) from 表 ...

  6. linux命令之----sort命令用于将文本文件内容加以排序

    1.sort命令作用 sort命令用于将文本文件内容加以排序,将输入行按照键值字段与数据类型选项以及locale排序. 一个可预期的记录次序,会让用户的查看使用更方便:书的索引.字典.目录以及电话簿等 ...

  7. JavaWeb网站后台开发记录手册

    1.javaweb网站后台开发 1.封装DBTools类 1.注册数据库驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); 2 ...

  8. Codeforces Beta Round #72 (Div. 2 Only)

    Codeforces Beta Round #72 (Div. 2 Only) http://codeforces.com/contest/84 A #include<bits/stdc++.h ...

  9. 微信小程序开发——小程序分享转发

    关于小程序的转发: 最简单的就是点击小程序右上角菜单“转发”按钮直接分享,不过这种分享有点不太友好,实用性也不强. 当然,你可以自定义分享内容,包括标题,简介,图片及分享的小程序页面路径. 再高级一点 ...

  10. f5会话保持导致站点访问故障

    1.环境: vs Service Port为443和80,vip为10.160.100.66,pool为10.160.45.42/43的8080.80的vs重新到443. 2.问题: 单独访问源站都没 ...