leetcode【121+122+123 best time to buy and sell stock】【python】
我們先拿出來前三道題,因為他們都是array中的題目。這是leetcode種經典的一系列題,涉及到動態規劃和貪心演算法。按照我的理解,貪心是滿足當前條件的最優值我們就將它最為最優解,也就是大家說的區域性最優值,而動態規劃是要記錄下來達到當前最優解的所有途徑,由區域性一步步得到全域性最優。
這幾道題都是給你一個股票每日價格表,讓你得到不同條件下能掙的最多的錢。
121題是隻允許買賣一次,要保證賣的時間晚於買的日期,第一反應找最大值和最小值,最大的早於最小的,那麼就找次大和次小,這樣肯定很麻煩,從這個過程已經能感受到一點動態規劃的感覺。是的沒錯,這道題就是用動態規劃,我們維持兩個變數,最低買入價格和當前可達到的最高利潤,從第二天開始遍歷,小於最低價格那麼我們更新最低價格變數,然後以這一天的價格作為賣出價格,那麼利潤就是賣出價格-最低價格,最次也就是0,也就是我更新了最低價格還以最低價格賣出去了,因為不能用之前的價格賣,此時利潤也要相應的更新,大於儲存的最大利潤我們就更新,遍歷完成後得到結果。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if(len(prices) <= 1):
return 0
buy_price = prices[0]
max_profit = 0
for i in range(1,len(prices)):
buy_price = min(buy_price, prices[i])
max_profit = max(max_profit, prices[i] - buy_price)
return max_profit
122題是說不限制買賣股票的次數,只要保證你賣的日期晚於買的日期即可。這個就適合用貪心演算法,只要當前比前一天的大,那麼我們就賣了股票。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
maxpro = 0
for i in range(1,len(prices)):
if prices[i] > prices[i-1 ]:
maxpro += prices[i] - prices[i-1]
return maxpro
123是由121演變而來的,原來是隻能有一次,現在是可以有兩次,這裡有要求是說你不能買一次再買一次然後賣出去兩次,只能買賣買賣。這個做法就比較有趣了,是將天數分開,前i天呼叫一次121的演算法,後面的天呼叫一次121的演算法,但是要注意如果外層迴圈i,裡面再迴圈121的演算法,會超時,這時我們考慮用兩個陣列來儲存結果,pre_profit和pro_profit,其中pre_profit[i]表示i天之前的最大利潤,pro_profit[i]表示i天之後的最大利潤,前i天的很好理解和121一樣的寫法,後i天注意要從後往前動態規劃。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
n = len(prices)
if(n<2):
return 0
pre_max_profit = [0 for i in range(n)]
pro_max_profit = [0 for i in range(n)]
max_profit = 0
pre_min_buy = prices[0]
for i in range(1,n):
#pre i days
pre_min_buy = min(pre_min_buy,prices[i])
pre_max_profit[i]=max(pre_max_profit[i-1], prices[i]-pre_min_buy)
pro_max_sell = prices[n-1]
for k in range(n-2,-1,-1):
pro_max_sell = max(pro_max_sell,prices[k])
pro_max_profit[k]=max(pro_max_profit[k+1], pro_max_sell-prices[k])
for j in range(0,n):
max_profit = max(max_profit,pre_max_profit[j]+pro_max_profit[j])
return max_profit