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