代码随想录刷题记录day44 股票问题3 4
123. 买卖股票的最佳时机 III
思想
-
dp数组定义
-
递推公式
dp[i][0] 第i天不操作股票手头最大的现金 i从0开始
dp[i][1] 第i天第一次持有股票的手头最大的现金
dp[i][1]= max: i-1天不操作,第i天才买入:dp[i-1][0]-prices[0];i-1天已经持有勒:dp[i-1][1]
dp[i][2] 第i天第一次卖出股票的手头最大的现金
dp[i][2]=max : i-1天持有股票: dp[i-1][1]+prices[i]; i天没有操作:dp[i-1][2]
dp[i][3] 第i天第二次持有股票的手头最大的现金
dp[i][2]=max :i-1天第一次卖出股票勒,i天买入:dp[i-1][2]-prices[i]; i-1天还是第二次持有股票的状态,i天没有操作 dp[i-1][3]
dp[i][4] 第i天第二次卖出股票的手头最大的现金
dp[i-1][4]=max: i-1天第二次持有股票,i天卖出 : dp[i-1][3]+prices[i]; i天不操作 dp[i-1][4]
-
初始化
int [][] dp=new int[prices.length][5]; dp[0][0]=0; dp[0][1]=-prices[0]; dp[0][2]=0; dp[0][3]=-prices[0]; dp[0][4]=0;
-
遍历顺序
依赖于前一个的状态
-
打印
代码
class Solution {
public int maxProfit(int[] prices) {
//1.dp数组的定义
//dp[i][0] 第i天不操作股票手头最大的现金 i从0开始
//dp[i][1] 第i天第一次持有股票的手头最大的现金
//dp[i][1]= max: i-1天不操作,第i天才买入:dp[i-1][0]-prices[0];i-1天已经持有勒:dp[i-1][1]
//dp[i][2] 第i天第一次卖出股票的手头最大的现金
//dp[i][2]=max : i-1天持有股票: dp[i-1][1]+prices[i]; i天没有操作:dp[i-1][2]
//dp[i][3] 第i天第二次持有股票的手头最大的现金
//dp[i][2]=max :i-1天第一次卖出股票勒,i天买入:dp[i-1][2]-prices[i]; i-1天还是第二次持有股票的状态,i天没有操作 dp[i-1][3]
//dp[i][4] 第i天第二次卖出股票的手头最大的现金
//dp[i-1][4]=max: i-1天第二次持有股票,i天卖出 : dp[i-1][3]+prices[i]; i天不操作 dp[i-1][4]
//2.dp 递推公式
//3.初始化
int [][] dp=new int[prices.length][5];
dp[0][0]=0;
dp[0][1]=-prices[0];
dp[0][2]=0;
dp[0][3]=-prices[0];
dp[0][4]=0;
//4.遍历顺序
for(int i=1;i<prices.length;i++){
dp[i][0]=dp[i-1][0];
dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
dp[i][2]=Math.max(dp[i-1][1]+prices[i],dp[i-1][2]);
dp[i][3]=Math.max(dp[i-1][2]-prices[i],dp[i-1][3]);
dp[i][4]=Math.max(dp[i-1][3]+prices[i],dp[i-1][4]);
}
return dp[prices.length-1][4];
}
}
188. 买卖股票的最佳时机 IV
思想
和上一题 的思想差不多,上一题是买卖2次,所以状态有5个
买卖k次,状态应该是2k+1个
用一个下标j来维护第i天不同次数的买入和卖出的状态
j+1表示买入状态
j+2表示卖出状态
for(int j=0;j<2*k;j+=2){
dp[i][j+1]=Math.max(dp[i-1][j]-prices[i],dp[i-1][j+1]);//j+1表示买入状态 延续之前的状态 或者是之前没有买入,此次买入了
dp[i][j+2]=Math.max(dp[i-1][j+1]+prices[i],dp[i-1][j+2]);
}
代码
class Solution {
public int maxProfit(int k, int[] prices) {
int[][] dp=new int[prices.length][2*k+1];
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;j+=2){
dp[i][j+1]=Math.max(dp[i-1][j]-prices[i],dp[i-1][j+1]);//j+1表示买入状态 延续之前的状态 或者是之前没有买入,此次买入勒
dp[i][j+2]=Math.max(dp[i-1][j+1]+prices[i],dp[i-1][j+2]);
}
}
return dp[prices.length-1][2*k];
}
}
参考:代码随想录