一、只能买卖一次
股票只能买卖一次,问最大利润
class Solution {
public int maxProfit(int[] prices) {
//0:持有股票
//1:不持有
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
for(int i = 1;i<prices.length;i++){
dp[i][0] = Math.max(dp[i-1][0],-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return dp[prices.length-1][1];
}
}
二、可以买卖多次
可以多次买卖股票,问最大收益
注意点:和上题的区别在于,本题的股票可以买卖多次! 所以买入股票的时候,可能会有之前买卖的利润
class Solution {
public int maxProfit(int[] prices) {
//0:持有股票
//1:不持有
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
for(int i = 1;i<prices.length;i++){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return dp[prices.length-1][1];
}
}
三、最多买卖两次
最多买卖两次,问最大收益
class Solution {
public int maxProfit(int[] prices) {
//0 第一次持有 1 第一次不持有
//2 第二次持有 3 第二次不持有
int[][] dp = new int[prices.length][4];
dp[0][0] = -prices[0];
dp[0][2] = -prices[0];
for(int i = 1;i<prices.length;i++){
dp[i][0] = Math.max(dp[i-1][0],-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1]-prices[i]);
dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2]+prices[i]);
}
return dp[prices.length-1][3];
}
}
四、最多买卖k次
最多买卖k笔交易,问最大收益
class Solution {
public int maxProfit(int k, int[] prices) {
int[][] dp = new int[prices.length][2*k+1];
//奇:持有
//偶(0除外):不持有
for(int i = 1;i<2*k;i+=2){
dp[0][i] = -prices[0];
}
for(int i = 1;i<prices.length;i++){
for(int j = 0;j<2*k-1;j+=2){
//偶
dp[i][j+2] = Math.max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
//奇
dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][j]-prices[i]);
}
}
return dp[prices.length-1][2*k];
}
}
五、买卖多次,卖出有一天冷冻期
可以多次买卖但每次卖出有冷冻期1天
分为四种状态:
1、持有股票
2、不持有股票:其中又分为维持不持有股票的状态、今天卖出股票和冷冻期三种
class Solution {
public int maxProfit(int[] prices) {
//持有股票 0:维持状态
// 今天刚买的:前一天是冷冻期/前一天不是冷冻期,就是卖出股票状态
//不持有股票 1:维持状态(前两天卖出股票,前一天是冷冻期/前2+n天卖出股票,前一天不是冷冻期)
// 2:今天卖出股票
// 3:冷冻期(前一天卖出股票)
int[][] dp = new int[prices.length][4];
dp[0][0] = -prices[0];
for(int i = 1;i<prices.length;i++){
dp[i][0] = Math.max(Math.max(dp[i-1][0],dp[i-1][3]-prices[i]),dp[i-1][1]-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][3]);
dp[i][2] = dp[i-1][0]+prices[i];
dp[i][3] = dp[i-1][2];
}
return Math.max(Math.max(dp[prices.length-1][1],dp[prices.length-1][2]),dp[prices.length-1][3]);
}
}
六、买卖多次,每次有手续费
class Solution {
public int maxProfit(int[] prices, int fee) {
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
for(int i = 1;i<prices.length;i++){
dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]-fee);
}
return Math.max(dp[prices.length-1][0],dp[prices.length-1][1]);
}
}