买卖股票-力扣

力扣中有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/

一、只存在一次买卖交易

买卖股票-力扣_第1张图片
- 用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 

二、多次买卖交易

买卖股票-力扣_第2张图片
- 买进股票,当第二天售价高时就卖出,第三天比第二天还高时,就在第三天卖出,此时利润等于第二天卖出的利润加上第三天与第二天的售价差值。

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

三、限定交易次数

买卖股票-力扣_第3张图片
初始化四个变量,然后遍历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

四、有冷冻期

买卖股票-力扣_第4张图片
第 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

买卖股票-力扣_第5张图片
需要考虑传入的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]

六、含手续费

买卖股票-力扣_第6张图片

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

你可能感兴趣的:(LeetCode,算法)