一、123.买卖股票的最佳时机III
注意的点:
- 若是想用三维数组表示dp,则相较买卖股票Ⅱ,需要注意的点是:需要多一层循环来遍历交易次数,同时交易买入的时候是在前一个交易的基础上-prices[i]。
- 若是想直接用压缩空间的方式,则使用四个变量buy1、sell1、buy2、sell2。关键点:buy2是在sell1的基础上 - prices[i],即在第一笔交易完成后才在第一笔交易剩余金钱的基础上进行第二笔交易的买入。
以下是代码部分:
public class 买卖股票的最佳时机III123 {
public int maxProfit(int[] prices) {
int buy1 = -prices[0],sell1 = 0;
int buy2 = -prices[0],sell2 = 0;
for (int i = 0; i < prices.length; i++) {
buy1 = Math.max(buy1, -prices[i]);
sell1 = Math.max(sell1, buy1 + prices[i]);
buy2 = Math.max(buy2, sell1 - prices[i]);
sell2 = Math.max(sell2, buy2 + prices[i]);
}
return sell2;
}
}
二、188.买卖股票的最佳时机IV
注意的点:
- 其实用三维dp数组更容易表示dp(天数、交易次数、拥有股票状态)
- 也可以将三维压缩成二维,其中第二维并不表示交易次数,而是买入和卖出总次数,其中奇数表示买入,偶数表示卖出。
以下是代码部分:
public class 买卖股票的最佳时机IV188 {
public int maxProfit(int k, int[] prices) {
//i:表示第i天,
int[][] dp = new int[prices.length][2*k+1];
//初始化
dp[0][0] = 0;
for (int j = 0; j < 2*k; j+=2) {
//奇数表示完成n个轮回后,又买入了一次
dp[0][j+1] = -prices[0];
//偶数表示完成了买入卖出一个轮回,所以是0
dp[0][j+2] = 0;
}
//遍历,外层天数,内层交易数
for (int i = 1; i < prices.length; i++) {
for (int j = 0; j < 2*k; j+=2) {
//注意,在递归公式中使用的都是 i- 1
//奇数,买入的最大值(当天需要买入,当天不需要买入)
dp[i][j+1] = Math.max(dp[i - 1][j] - prices[i], dp[i - 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];
}
}