買股票的最佳時機(一次買入一次賣出,兩次,多次)

朋克歸零膏發表於2020-12-17

一次買入和一次賣出的情況

解法一:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        miniprice = float('inf')
        maxprofit = 0
        for price in prices:
            miniprice = min(miniprice, price)
            maxprofit = max(maxprofit, price-miniprice)
        return maxprofit

解法二:
dp[i]表示第i天最大收益dp[i] = max(dp[i-1], price[i] - miniprice)

class Solution:
   def maxProfit(self, prices: List[int]) -> int:
       if not prices:
           return 0
       else:
           dp = [0 for _ in range(len(prices))]
           miniprice = prices[0]
           for i in range(1, len(prices)):
               miniprice = min(miniprice, prices[i])
               dp[i] = max(dp[i-1], prices[i]-miniprice)
           return dp[-1]

兩次買入賣出的情況

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        dp = [0 for _ in range(5)]
        dp[0] = 0
        dp[1] = -prices[0]
        dp[2] = float('-inf')
        dp[3] = -prices[0]
        dp[4] = float('-inf')
        for i in range(len(prices)):
            # 如果價格比昨天低就更新第一次買入的價格
            dp[1] = max(dp[1], dp[0]-prices[i])
            # 如果賣出價格比昨天賣出的價格高就更新
            dp[2] = max(dp[2], dp[1]+prices[i])
            # 同第一次的操作,不過這時候已經有第一次買賣的收入
            dp[3] = max(dp[3], dp[2]-prices[i])
            dp[4] = max(dp[4], dp[3]+prices[i])
        return max(dp)

兩次買賣的話拆分成5種狀態:
dp[0] 沒有進行買賣
dp[1] 第一次買入
dp[2] 第一次賣出
dp[3] 第二次買入
dp[4] 第二次賣出

我覺得問題的關鍵在於,第一次和第二買賣不會進行交叉,所以第一次買了之後只能賣了才進行下一次買賣,這樣問題的狀態拆分就很簡單了。動態規劃解法的話需要初始狀態和狀態公式。

初始狀態:假設當天買或者不買,dp[0]顯然是0,dp[2]和dp[4]顯然還沒賣出是沒有收益的,dp[1]和dp[3]買入肯定是扣除當天的價格的。

總的來說配合程式碼不難理解,思路是dp[i]代表當前狀態的收益。

不限次數買入賣出

題目改成這樣之後又變得簡單了。自行腦補一個月k線,題目的意思是我們可以馬後炮,知道走勢的情況下,如何做到最大收益——就是把所有上升的曲線都買了。
大佬講的實在太好了。忍不住引用
在這裡插入圖片描述

作者:jyd
連結:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/best-time-to-buy-and-sell-stock-ii-zhuan-hua-fa-ji/ 來源:力扣(LeetCode) 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        profit = 0
        for i in range(1,len(prices)):
            tmp = prices[i] - prices[i-1]
            if tmp>0:
                profit += tmp
        return profit

相關文章