Day12 股票问题(02)
1、123. 买卖股票的最佳时机 III
- 思路:
- 股票问题解题模板。
- 注意base case
- k从1开始,最大取2。
- 第0天没有未持有股票,则收益一定为0
- 第0天持有股票,则最大收益一定是-price[0]
class Solution { public int maxProfit(int[] prices) { int len = prices.length; int[][][] dp = new int[len][3][2]; for (int i = 0; i < len; i++) { for (int k = 1; k < 3; k++) { if (i == 0) { // 处理 base case dp[i][k][0] = 0; dp[i][k][1] = -prices[i]; continue; } dp[i][k][0] = Math.max(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]); dp[i][k][1] = Math.max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i]); } } return dp[len - 1][2][0]; } } - 股票问题解题模板。
- 空间复杂度优化(辅助理解base case)
class Solution { public int maxProfit(int[] prices) { int len = prices.length; //每天一共五种状态 没有买卖 第一次买入 第一次卖出 完成一次买卖买入 完成一次买卖卖出 //base case buy1第一天买入 buy2 第一天买卖一次为0,再买一次=buy1 int buy1 = -prices[0], buy2 = -prices[0]; //sell 第一天买卖利润为0 第一天买卖两次还为0 int sell1 = 0, sell2 = 0; for (int i = 1; i < len; 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; } }
2、188. 买卖股票的最佳时机 IV
- 股票模板
class Solution { public int maxProfit(int k, int[] prices) { int len = prices.length; int[][][] dp = new int[len][k + 1][2]; for (int i = 0; i < len; i++) { dp[i][0][0] = 0; dp[i][0][1] = Integer.MIN_VALUE; } for (int i = 0; i < len; i++) { //k从1开始 for (int j = 1; j < k + 1; j++) { if (i == 0) { //第0天买卖k次未持有股票的最大收益为0 dp[i][j][0] = 0; //第0天买卖k次持有股票的最大收益为-prices[0] dp[i][j][1] = -prices[i]; continue; } dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]); dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]); } } return dp[len - 1][k][0]; } } - 空间复杂度优化
- 同1解法思路一致,取buy[]和sell[]数组
class Solution { public int maxProfit(int k, int[] prices) { int len = prices.length; if (len == 0) return 0; int[] buy = new int[k]; int[] sell = new int[k]; Arrays.fill(buy, -prices[0]); for (int i = 1; i < len; i++) { buy[0] = Math.max(buy[0], -prices[i]); sell[0] = Math.max(sell[0], buy[0] + prices[i]); for (int j = 1; j < k; j++) { buy[j] = Math.max(buy[j], sell[j - 1] - prices[i]); sell[j] = Math.max(sell[j], buy[j] + prices[i]); } } return sell[k - 1]; } }