题目与题解
参考资料:买卖股票总结
309.最佳买卖股票时机含冷冻期
题目链接:309.最佳买卖股票时机含冷冻期
代码随想录题解:309.最佳买卖股票时机含冷冻期
视频讲解:动态规划来决定最佳时机,这次有冷冻期!| LeetCode:309.买卖股票的最佳时机含冷冻期_哔哩哔哩_bilibili
解题思路:
听说状态比较多,直接放弃看答案,状态转移有点复杂的。
看完代码随想录之后的想法
关键是要理解在有冷冻状态的条件下,股票可能有哪些状态,它们之间的关系是什么,才能直到状态变化的依赖关系,得出状态转移公式。
具体可以区分出如下四个状态:
- 状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)
- 不持有股票状态,这里就有两种卖出股票状态
- 状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)
- 状态三:今天卖出股票
- 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
那么转移到状态一有三种情况:保持买入状态不变,不买不卖(状态1->1);刚结束冷冻状态,直接买入(状态4->1);处于卖出一段时间的状态,再买入(状态2->1)
转移到状态2有两种情况:前面没有冷冻,保持卖出状态不变,不买不卖(状态2->2);刚结束冷冻状态,但不买入,保持卖出状态(状态4->2)
转移到状态3只有一种情况:处于买入状态,然后卖出(状态1->3)
转移到状态4只有一种情况:刚卖出(状态3->4)
递推公式根据状态转移就可以清楚的得到了。初始化状态1为-prices[0],其余状态由于还未产生交易,初始化为0。
最后返回时,要从状态2,3,4中选一个最大值。因为今天卖出,冷冻,和保持卖出状态这三种都属于卖出的状态,有可能都有最大值。
class Solution {
public int maxProfit(int[] prices) {
if (prices.length <= 1) return 0;
int[][] dp = new int[prices.length][4];
dp[0][0] = -prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i-1][0], Math.max(dp[i-1][1]-prices[i], dp[i-1][3]-prices[i]));
dp[i][1] = Math.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];
}
return Math.max(dp[prices.length-1][1], Math.max(dp[prices.length-1][2], dp[prices.length-1][3]));
}
}
遇到的困难
第一次遇到这么复杂的状态,记下了
714.买卖股票的最佳时机含手续费
题目链接:714.买卖股票的最佳时机含手续费
代码随想录题解:714.买卖股票的最佳时机含手续费
视频讲解:动态规划来决定最佳时机,这次含手续费!| LeetCode:714.买卖股票的最佳时机含手续费_哔哩哔哩_bilibili
解题思路:
这题跟买卖股票II几乎一样,就是在卖出状态时,如果卖出了股票,需要增加一个手续费,即dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)。最后仍旧返回dp[prices.length-1][1]即可。
class Solution {
public int maxProfit(int[] prices, int fee) {
if (prices.length <= 1) return 0;
int[][] dp = new int[prices.length][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < prices.length; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] - prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i] - fee);
}
return dp[prices.length-1][1];
}
}
看完代码随想录之后的想法
无
遇到的困难
写dp[i][0]递推公式的时候一开始思路不清晰写成了dp[i-1][0] - prices[i],这肯定不对,要牢记卖出后才能买入,必然用dp[i-1][1] - prices[i]来递推。
今日收获
学习了一下复杂状态的买卖股票方法, 复习总结了买卖股票系列问题。
买卖股票问题的核心解法是定义dp为手中持有的现金,再根据买入卖出加减持有值。
买卖一次和买卖多次的状态转移方法有点类似,最后可以用公式总结出来;如果出现类似冷冻期,手续费之类的特殊值,需要判断其状态转移是否有变化,递推公式是否需要修改,基本公式就是买卖股票IV里的规律总结了。