买卖股票的最佳时机(III)

原文:https://blog.csdn.net/linhuanmars/article/details/23236995 
 

这里我们先解释最多可以进行k次交易的算法,然后最多进行两次我们只需要把k取成2即可。我们还是使用“局部最优和全局最优解法”。我们维护两种量:

  1. global[i][j]:一个是当前到达第i天可以最多进行j次交易,最好的利润是多少
  2. 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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值