【Leetcode】188. Best Time to Buy and Sell Stock IV 188. 买卖股票的最佳时机 IV
解法
参考:https://blog.****.net/danielrichard/article/details/75091410
从上次那个两个交易里扩展出来的
上次的解法为:
firstBuy[i] = max(firstBuy[i - 1], -prices[i]) # 在前i天完成至多1次买入
firstSell[i] = max(firstSell[i - 1], firstBuy[i - 1] + prices[i]) # 在前i天完成至多1次卖出
secondBuy[i] = max( secondBuy[i - 1], firstSell[i - 1] - prices[i]) # 在前i天完成至多2次买入
secondSell[i] = max( secondSell[i - 1], secondBuy[i - 1] + prices[i]) # 在前i天完成至多2次卖出
最后返回secondSell[-1]
就行
发现每个i
只和i-1
有关系。
我们用buy[i][k]
表示在前i天完成至多k次买入的最大收益
用sell[i][k]
表示在前i天完成至多k次卖出的最大收益。
我们同样可以得到:
buy[i][1] = max(buy[i-1][1],-prices[i])
sell[i][1] = max(sell[i-1][1],buy[i-1][1]+prices[i])
...
buy[i][k] = max(buy[i-1][k],sell[i-1][k-1]-prices[i])
sell[i][k] = max(sell[i-1][k],buy[i-1][k]+prices[i])
最后返回sell[-1][-1]
就行
由于i只跟i-1有关系,所以可以用省空间的方法,把k从大到小遍历即可。
这道题还有其它的坑:
- 当
k==0
或者n==0
的时候直接返回0 - 如果k过大,即
k>=n//2
,那么只要有收益我就可以交易,用贪心法求解
class Solution(object):
def maxProfit(self, K, prices):
"""
:type k: int
:type prices: List[int]
:rtype: int
"""
"""
buy[i][k] = max(buy[i-1][k],sell[i-1][k-1]-prices[i])
sell[i][k] = max(sell[i-1][k],buy[i-1][k]+prices[i])
"""
n = len(prices)
if n==0 or K==0:
return 0
if K>=n//2:
res = 0
for i,p in enumerate(prices[1:]):
res += max(0,p-prices[i])
return res
buy = [-prices[0]]*K
sell = [0]*K
for p in prices[1:]:
for k in xrange(K-1,0,-1):
sell[k] = max(sell[k],buy[k]+p)
buy[k] = max(buy[k],sell[k-1]-p)
sell[0] = max(sell[0],buy[0]+p)
buy[0] = max(buy[0],-p)
return sell[-1]