目录
题目1: 123. 买卖股票的最佳时机 III
- 题目链接:123. 买卖股票的最佳时机 III
1- 思路
思路
- 与前者的区别
- 买卖股票1:只能买卖股票一次
- 买卖股票2:在数组中可以买卖多次
- 买卖股票3:本题只可以买卖两次
动规五部曲
- 1. 确定 dp 数组含义
- dp[i][0] :不操作
- dp[i][1]:第一次持有(并不是第 i 天一定买入,可以延续之前买入的状态)
- dp[i][2]:第一次不持有(并不是第 i 天一定卖出,可以延续之前卖出的状态)
- dp[i][3]:第二次持有
- dp[i][4]:第二次不持有
- 2. 确定递推公式
dp[i][0] = dp[i-1][0]
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])
- 第二次持有,可以通过 前一天持有 和 第二次买入 推导而来
dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+prices[i])
- 第二次不持有,可以通过 前一天不持有 和 当天卖出 推导而来
- 3. dp 数组初始化
- dp[0][0] = 0
- dp[0][1] = -prices[0]
- dp[0][2] = 0 :同一天买卖,相当于手上现金为 0
- dp[0][3] = -prices[0]
- dp[0][4] = 0
- 4. 遍历顺序
- i 从 1 遍历整个数组的 size
- 5. 推导 dp 数组
- dp[prices.length-1][4] 就是结果值
2- 题解
⭐买卖股票的最佳时机 III——题解思路
class Solution {
public int maxProfit(int[] prices) {
// 1. dp 数组及创建
int[][] dp = new int[prices.length][5];
// 2.递推公式
// 不操作 dp[i][0] = dp[i-1][0];
// 持有一次 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]);
// 第二次不持有 dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);
// 3.初始化
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][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]);
dp[i][4] = Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);
}
return dp[prices.length-1][4];
}
}
题目2:188. 买卖股票的最佳时机 IV
- 题目链接:188. 买卖股票的最佳时机 IV
1- 思路
思路
- 与前者的区别
- 买卖股票1:只能买卖股票一次
- 买卖股票2:在数组中可以买卖多次
- 买卖股票3:本题只可以买卖两次
- 买卖股票4:本题只可以买卖K次
动规五部曲
- 1. 确定 dp 数组含义
dp[prices.length][2*k+1]
- 2. 确定递推公式
dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][j]-prices[i]);
dp[i][j+2] = Math.max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
- 3. dp 数组初始化
j
从1
开始,每次跳跃2
,初始化奇数下标为-prices[0]
- 4. 遍历顺序
i
从1
到prices.length
j
从0
到j < 2*k
- 5. 推导 dp 数组
return dp[prices.length-1][2*k]
2- 题解
⭐买卖股票的最佳时机 IV——题解思路
class Solution {
public int maxProfit(int k, int[] prices) {
// 1. dp创建
int[][] dp = new int[prices.length][2*k+1];
// 2. dp递推公式
// 不操作 dp[i][0] = do[i-1][0]
// 持有 dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][0]-prices[i]);
// 不持有 dp[i][j+2] = Math.max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
// 3. 初始化
for(int j = 1 ; j< 2*k;j+=2){
dp[0][j] = -prices[0];
}
// 遍历
for(int i = 1 ; i <prices.length;i++){
for(int j = 0; j < 2*k ;j+=2){
// dp[i][0] = dp[j-1][0];
dp[i][j+1] = Math.max(dp[i-1][j+1],dp[i-1][j]-prices[i]);
dp[i][j+2] = Math.max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);
}
}
return dp[prices.length-1][2*k];
}
}