之前介绍了【LeetCode 买卖股票的最佳时机】系列一共六道题目,这里把之前的题解还有题目链接汇总一下,方便大家查找。
LeetCode 121. 买卖股票的最佳时机[1]
每日算法系列【LeetCode 121】买卖股票的最佳时机
LeetCode 122. 买卖股票的最佳时机 II[2]
每日算法系列【LeetCode 122】买卖股票的最佳时机 II
LeetCode 123. 买卖股票的最佳时机 III[3]
每日算法系列【LeetCode 123】买卖股票的最佳时机 III
LeetCode 188. 买卖股票的最佳时机 IV[4]
每日算法系列【LeetCode 188】买卖股票的最佳时机 IV
LeetCode 714. 买卖股票的最佳时机含手续费[5]
每日算法系列【LeetCode 714】买卖股票的最佳时机含手续费
LeetCode 309. 最佳买卖股票时机含冷冻期[6]
每日算法系列【LeetCode 309】最佳买卖股票时机含冷冻期
上面六道题目中,前四题限制了买卖的次数,第五题加入了手续费,第六题加入了冻结时间。所以我们提出一般性的问题:
给定每天的价格 ,最大买卖次数 ,手续费 ,冻结时间 ,求最大利润。
观察前面六题的代码,我们可以在第四题基础上进行修改,这样代码量比较小。
首先是增加手续费,这个很简单,只需要在 更新时减去一个手续费 就行了。
有点麻烦的是冻结时间。在第六题代码中,增加了一个维度用来保存每一只股票之前(包含)的最大利润,目的是为了获取相隔一个冻结时间之前的股票以前可以获得的最大利润。但是通用情况下不能这么保存,不然的话空间复杂度就变成了 ,极限情况下会爆掉。
解决方法就是,因为对于第 只股票来说,只需要访问它与 之间的数值,那么我们只需要保存 大小的数组就行了。在访问的时候,采用取模的方法,来让数组滚动起来。
还有一些细节,比如如果 ,那么问题就退化为了没有买卖次数限制,也就是第五题和第六题的情况。如果不这样处理的话,按照上面方法做,时间复杂度和空间复杂度都是 ,可能会吃不消。
class Solution:
def solve(self, prices, k=1, fee=0, freeze=0):
n = len(prices)
if n == 0 or k == 0: return 0
limit = 0 if k >= n//2 else 1
k = 1 if k >= n//2 else k
dp0 = [-prices[0]] * (k+1)
dp1 = [[0]*(k+1) for _ in range(freeze+1)]
for i in range(1, n):
for j in range(1, k+1):
dp0[j] = max(dp0[j], dp1[i%(freeze+1)][j-1 if limit else j]-prices[i])
dp1[i%(freeze+1)][j] = max(dp1[(i-1)%(freeze+1)][j], dp0[j]+prices[i]-fee)
return max(dp1[(n-1)%(freeze+1)][k], 0)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
return self.solve(prices, k=1, fee=0, freeze=0)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
return self.solve(prices, k=len(prices), fee=0, freeze=0)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
return self.solve(prices, k=2, fee=0, freeze=0)
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
return self.solve(prices, k, fee=0, freeze=0)
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
return self.solve(prices, len(prices), fee, 0)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
return self.solve(prices, k=len(prices), fee=0, freeze=1)
[1]
LeetCode 121. 买卖股票的最佳时机: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
[2]LeetCode 122. 买卖股票的最佳时机 II: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
[3]LeetCode 123. 买卖股票的最佳时机 III: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/
[4]LeetCode 188. 买卖股票的最佳时机 IV: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/
[5]LeetCode 714. 买卖股票的最佳时机含手续费: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/
[6]LeetCode 309. 买卖股票的最佳时机: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
推荐阅读
1、【算法提高班】《贪婪策略》系列 - 覆盖篇
2、【LeetCode日记】 335. 路径交叉
3、一行代码就可以通过 LeetCode?来看下我是怎么做到的!
4、原来状态机也可以用来刷LeetCode?
5、【算法提高班】《我的日程安排表》系列
6、【算法提高班】并查集
如果觉得文章不错,帮忙点个在看呗