买卖股票-力扣

力扣中有6题关于股票的问题,我们先从最简单的出发,逐步解决所有问题。
参考大佬们的解答,发现有一个用状态机的方法,比较通用且好理解。参考:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/solution/yi-ge-tong-yong-fang-fa-tuan-mie-6-dao-gu-piao-wen/

一、只存在一次买卖交易

在这里插入图片描述
- 用imin记录遍历过程中的最小值,imax记录到遍历的数据前的最大利润

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        imax,imin=0,float("inf")
        for price in prices:
            if imin>price:
                imin=price
            elif price-imin>imax:
                    imax=price-imin
        return imax 

二、多次买卖交易

在这里插入图片描述
- 买进股票,当第二天售价高时就卖出,第三天比第二天还高时,就在第三天卖出,此时利润等于第二天卖出的利润加上第三天与第二天的售价差值。

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        res=0
        for i in range(1,len(prices)):
            diff=prices[i]-prices[i-1]
            if diff>0:
                res+=diff
        return res

三、限定交易次数

在这里插入图片描述
初始化四个变量,然后遍历prices,dp_20进行第二笔交易且手里不含股票,它由前一次于此同样状态和前一次进行第二笔交易手里买进股票转变而来。以此每一个状态都可以推导。

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:
            return 0
        dp_10,dp_20=0,0
        dp_11,dp_21=-float("inf"),-float("inf")
        for price in prices:
            dp_20=max(dp_20,dp_21+price)
            dp_21=max(dp_21,dp_10-price)
            dp_10=max(dp_10,dp_11+price)
            dp_11=max(dp_11,-price)
        return dp_20

四、有冷冻期

在这里插入图片描述
第 i 天选择 buy 的时候,要从 i-2 的状态转移,而不是 i-1

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        dp_0,dp_1=0,-float("inf")
        dp_pre=0
        for price in prices:
            tmp=dp_0
            dp_0=max(dp_0,dp_1+price)
            dp_1=max(dp_1,dp_pre-price)
            dp_pre=tmp
        return dp_0  

五、限定交易次数为K

在这里插入图片描述
需要考虑传入的k值超过了最大允许次数

class Solution(object):
    def maxProfit(self, k, prices):
        """
        :type k: int
        :type prices: List[int]
        :rtype: int
        """
        n=len(prices)
        if n<2 or k<1:return 0
        if k>n//2:
            res=0
            for i in range(1,len(prices)):
                diff=prices[i]-prices[i-1]
                if diff>0:
                    res+=diff
            return res
        dp=[[[0 for _ in range(2)] for _ in range(k+1)] for _ in range(n)]       
        for i in range(0,n):
            for j in reversed(range(1,k+1)):
                if i==0:
                    dp[0][j][1]=-prices[i]
                    continue
                dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]+prices[i])
                dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j-1][0]-prices[i])   
        return dp[n-1][k][0]

六、含手续费

在这里插入图片描述

class Solution(object):
    def maxProfit(self, prices, fee):
        """
        :type prices: List[int]
        :type fee: int
        :rtype: int
        """
        dp_0,dp_1=0,-float("inf")
        for price in prices:
            tmp=dp_0
            dp_0=max(dp_0,dp_1+price-fee)
            dp_1=max(dp_1,tmp-price)
        return dp_0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值