Day53 代码随想录算法训练营 第九章 动态规划 part12|309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费 、总结
今日内容
309.最佳买卖股票时机含冷冻期
714.买卖股票的最佳时机含手续费
总结
309.最佳买卖股票时机含冷冻期
问题:
给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

提示:
1 <= prices.length <= 50000 <= prices[i] <= 1000
思路:
注意:无法在第二天买入股票 (即冷冻期为 1 天)
① dp数组
dp[i][j]:第i天状态为j,所剩的最多现金为dp[i][j]。
i:[0, prices.length )
j: [0, 2*k+1)
状态:持有、不持有、冷冻
- dp[i][0]:持股(包含当天买入,以及之前买入)
- dp[i][1]:保持卖出状态
- dp[i][2]:卖出股票
- dp[i][3]:冷冻期
持有股票状态:dp[i][0]
① 当天买入(前一天是 冷冻期状态: dp[i-1][3]-prices[i])(前一天是 保持卖出股票的状态:dp[i-1][1]-prices[i])
② 前一天就持有股票了 dp[i-1][0]
保持卖出状态:dp[i][1]
①(前一天就是卖出状态了 dp[i-1][1])
②(当前是冷冻期,保持着卖出的状态 dp[i-1][3] )
卖出:dp[i][2]
当天卖出(dp[i-1][0] + prices[i])
冷冻期:dp[i][3]
前一天一定是卖出状态(dp[i-1][2])
② 递推公式
dp[i][0] = max(dp[i-1][3]-prices[i], dp[i-1][1]-prices[i], dp[i-1][0])
dp[i][1] = 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]
③ 初始化(从递推公式中看,需要我们将其初始化为多少)
dp[0][0] = -prices[0]
dp[0][1] = 0
dp[0][2] = 0
dp[0][3] = 0
④ 循环遍历
从前往后遍历
⑤ 举例推导dp数组

最后,取dp[len-1][1] dp[len-1][2] dp[len-1][3]得最大值

代码:
1 /* 2 * @lc app=leetcode.cn id=309 lang=javascript 3 * 4 * [309] 买卖股票的最佳时机含冷冻期 5 */ 6 7 // @lc code=start 8 /** 9 * @param {number[]} prices 10 * @return {number} 11 */ 12 var maxProfit = function(prices) { 13 let dp = new Array(prices.length).fill(0).map(() => new Array(4).fill(0)) 14 15 dp[0][0] = -prices[0]; 16 17 for (let i = 1; i < prices.length; i++) { 18 dp[i][0] = Math.max(dp[i - 1][0], Math.max(dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i])) 19 dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][3]) 20 dp[i][2] = Math.max(dp[i - 1][0] + prices[i]) 21 dp[i][3] = Math.max(dp[i - 1][2]) 22 23 24 } 25 let len = prices.length - 1; 26 return Math.max(dp[len][1], Math.max(dp[len][2], dp[len][3])) 27 };
714.买卖股票的最佳时机含手续费
问题:
给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

提示:
1 <= prices.length <= 5 * 1041 <= prices[i] < 5 * 1040 <= fee < 5 * 104
思路:
类似122. 两个状态 0(持有)1 (不持有)
直接AC
1 /* 2 * @lc app=leetcode.cn id=714 lang=javascript 3 * 4 * [714] 买卖股票的最佳时机含手续费 5 */ 6 7 // @lc code=start 8 /** 9 * @param {number[]} prices 10 * @param {number} fee 11 * @return {number} 12 */ 13 var maxProfit = function(prices, fee) { 14 let dp = new Array(prices.length).fill(0).map(() => new Array(2).fill(0)) 15 dp[0][0] = -prices[0]; 16 dp[0][1] = 0; 17 18 for (let i = 1; i < prices.length; i++) { 19 dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]) 20 dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee) 21 22 } 23 return dp[prices.length - 1][1]; 24 };
股票问题总结


浙公网安备 33010602011771号