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.
Solution 11st version
丑陋
class Solution {
int a1,a2;
public:
bool PredictTheWinner(vector<int>& nums) {
return PredictTheWinnerScoreFirst(nums,0,nums.size()-1,0,0);
}
bool PredictTheWinnerScoreFirst(vector<int>& nums,int l, int h, int a1, int a2) {
int s = h-l+1;
int t;
bool r;
if(1==s){
return a1+nums[l]>=a2;
}
if(2==s){
t = abs(nums[l] - nums[h]);
return a1+t>=a2;
}
//1. choose low
r = PredictTheWinnerScoreSecond(nums, l+1, h, a1+nums[l], a2);
if(r == false) return true;
//2. choose high
r = PredictTheWinnerScoreSecond(nums, l, h-1, a1+nums[h], a2);
if(r == false) return true;
return false;
}
bool PredictTheWinnerScoreSecond(vector<int>& nums,int l, int h, int a1, int a2) {
int s = h-l+1;
int t;
bool r;
if(1==s){
return a2+nums[l]>a1;
}
if(2==s){
t = abs(nums[l] - nums[h]);
return a2+t>a1;
}
//1. choose low
r = PredictTheWinnerScoreFirst(nums, l+1, h, a1, a2+nums[l]);
if(r == false) return true;
//2. choose high
r = PredictTheWinnerScoreFirst(nums, l, h-1, a1, a2+nums[h]);
if(r == false) return true;
return false;
}
};
优化:2nd version
进一步抽象,删除if(2--s)
class Solution {
int a1,a2;
public:
bool PredictTheWinner(vector<int>& nums) {
return PredictTheWinnerScoreFirst(nums,0,nums.size()-1,0,0);
}
bool PredictTheWinnerScoreFirst(vector<int>& nums,int l, int h, int a1, int a2) {
int s = h-l+1;
int t;
bool r;
if(1==s){
return a1+nums[l]>=a2;
}
//1. choose low
r = PredictTheWinnerScoreSecond(nums, l+1, h, a1+nums[l], a2);
if(r == false) return true;
//2. choose high
r = PredictTheWinnerScoreSecond(nums, l, h-1, a1+nums[h], a2);
if(r == false) return true;
return false;
}
bool PredictTheWinnerScoreSecond(vector<int>& nums,int l, int h, int a1, int a2) {
int s = h-l+1;
int t;
bool r;
if(1==s){
return a2+nums[l]>a1;
}
//1. choose low
r = PredictTheWinnerScoreFirst(nums, l+1, h, a1, a2+nums[l]);
if(r == false) return true;
//2. choose high
r = PredictTheWinnerScoreFirst(nums, l, h-1, a1, a2+nums[h]);
if(r == false) return true;
return false;
}
};
优化:3rd version
PredictTheWinnerScoreFirst 和 PredictTheWinnerScoreSecond 合并
class Solution {
public:
bool PredictTheWinner(vector<int>& nums) {
return helper(nums,0,nums.size()-1,0,true);
}
bool helper(vector<int>& nums,int l, int h, int t, bool isFirst) {
bool r;
if(l==h){
return isFirst? t+nums[l]>=0 : nums[l]>t;
}
//1. choose low
isFirst? t+=nums[l] : t-=nums[l];
r = helper(nums, l+1, h, t,!isFirst);
if(r == false) return true;
//2. choose high
isFirst? t+=nums[h] : t-=nums[h];
r = helper(nums, l, h-1, t,!isFirst);
if(r == false) return true;
return false;
}
};
Solution 2
1st version
class Solution {
int a1,a2;
public:
bool PredictTheWinner(vector<int>& nums) {
return helper(nums,0,nums.size()-1)>=0;
}
int helper(vector<int>& nums,int l, int h) {
int r1;
int r2;
if(l==h){
return nums[l];
}
//1. choose low
r1 = nums[l]-helper(nums,l+1,h);
//2. choose high
r2 = nums[h] - helper(nums, l, h-1);
return max(r1,r2);
}
};
2nd version 增加记忆
class Solution {
int t[20][20];
bool b[20][20];
public:
bool PredictTheWinner(vector<int>& nums) {
for(int i=0; i<20; i++){
for(int j=0; j<20; j++){
b[i][j] = false;
}
}
return helper(nums,0,nums.size()-1)>=0;
}
int helper(vector<int>& nums,int l, int h) {
if(b[l][h]) return t[l][h];
int r1;
int r2;
if(l==h){
return nums[l];
}
//1. chose low
r1 = nums[l]-helper(nums,l+1,h);
//2. chose high
r2 = nums[h] - helper(nums, l, h-1);
b[l][h] = true;
t[l][h] = max(r1,r2);
return t[l][h];
}
};
最坏复杂度
W(n) = 2W(n-1)
W(n-1) = 2^2W(n-2)
W(2) = W(n-(n-2)) = 2^(n-1)W(1) = 2^(n-1)