原文:https://blog.csdn.net/linhuanmars/article/details/23236995
这里我们先解释最多可以进行k次交易的算法,然后最多进行两次我们只需要把k取成2即可。我们还是使用“局部最优和全局最优解法”。我们维护两种量:
- global[i][j]:一个是当前到达第i天可以最多进行j次交易,最好的利润是多少
- local[i][j]:另一个是当前到达第i天,最多可进行j次交易,并且最后一次交易在当天卖出的最好的利润是多少。
下面我们来看递推式:
- 全局变量,
global[i][j]=max(local[i][j],global[i-1][j]),
如果最后一次交易发生在i天,那么最优的结果就是local[i][j],否则,最优发生在前i-1天当中。
- 局部变量
local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),
分两种情况,最后一次交易发生在第i天,和最后一次交易发生在i-1天。发生在第i天时,global[i-1][j-1]+max(diff,0),也就是i-1天发生了j-1次交易,然后加上第i天的盈利情况,第二种是i-1天发生了j次交易,但是不符合要求,所以在第i-1天发生的交易要连带上第i天的交易,这样才满足local[i][j]的定义。
上面的算法中对于天数需要一次扫描,而每次要对交易次数进行递推式求解,所以时间复杂度是O(n*k),如果是最多进行两次交易,那么复杂度还是O(n)。空间上只需要维护当天数据皆可以,所以是O(k),当k=2,则是O(1)。
然后贴上python代码:
class Solution:
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
v=0
globalben=[v for k in range(3)]
localben=[v for k in range(3)]
count=len(prices)-1
for i in range(count):
diff=prices[i+1]-prices[i]
j=2
while j>0:
print(j)
localben[j]=max((globalben[j-1]+max(diff,0)),(localben[j]+diff))
globalben[j]=max(localben[j],globalben[j])
j-=1
return globalben[2]
不过我看评论区还有另一种算法,有点想不明白
class Solution:
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
first_buy, first_sell, second_buy, second_sell=-sys.maxsize, 0 ,-sys.maxsize, 0
for price in prices:
first_buy=max(-price,first_buy)
first_sell=max(first_sell,price+first_buy)
second_buy=max(second_buy,first_sell-price)
second_sell=max(second_sell,price+second_buy)
return second_sell