又到了晚上,動態規劃,開刷!
題目的意思:給予乙個陣列price,表示特定**在某天的股價,裡面第i個數表示第i天的**。只能交易一次(買一次+賣一次),求最大利潤
分析:典型的動態規劃。當我們要求到第i天為止最大的利潤,就需要知道i-1天為止的最大利潤,然後用第i天的股價減去(i-1)天**最低值,然後比較即可。所以我們可以推出狀態轉移方程:
maxprofit(i) = max(maxprofit(i-1), price[i] - min(price[:i]))
下面是**:
class solution:
# @param prices
# @return
def maxprofit(self, price):
maxprofit = 0
nextprofit = 0
profit = 0
if len(price) <= 1:
return 0
for i in range(1, len(price)):
nextprofit = max(profit, price[i] - min(price[:i]))
maxprofit = max(maxprofit, nextprofit)
profit = nextprofit
return maxprofit
可是這樣提交上去,返回了乙個執行超時..(未通過) 但是大體思路是正確的,所以我就想對這個程式進行改進。我注意到這幾個min
,max
函式上。要知道,雖然我們使用了這個python提供的函式,但是python的實現過程肯定不是o(1),肯定內部實現是需要排序的,這裡就和我的遍歷重複了! 所以我在for迴圈外新增了乙個變數minnum
:minnum = price[0]
用來記錄最小值,然後在for
迴圈中進行了如下修改:
for i in range(1, len(price)):
if price[i] < minnum:
minnum = price[i]
else:
nextprofit = max(profit, price[i] - minnum)
maxprofit = max(maxprofit, nextprofit)
profit = nextprofit
題目的意思:求和為最大的子串,例如陣列[−2,1,−3,4,−1,2,1,−5,4]
,它的最大子串為[4,−1,2,1]
,和為6
分析:如果當前和為負數,後面的數值加上當前和則必然小於原數值,則應將當前和丟棄
class solution:
# @param nums
# @return
def maxsubarray(self, nums):
cursum = 0
maxsum = -2147483648
for i in range(len(nums)):
if cursum <= 0:
cursum = nums[i]
else:
cursum += nums[i]
maxsum = max(maxsum, cursum)
return maxsum
比如陣列a=子串行和最大為5,最短的為a[5]
分析:首先,我們可以用上面的方法求出和最大的序列和,但是這裡我們可以使用乙個字典來儲存這個子串行。當遇到兩個子串行和一樣的時候,比較子串行長度,取長度小的那個。下面是**:
def maxsum(li):
cursum = 0
maxsum = -2147483648
templist = #增加乙個臨時列表變數,用於記錄子串行
shortdict = dict()
for i in range(len(li)):
if cursum > 0:
cursum += li[i]
else:
cursum = li[i]
templist[:] = #此時cursum<=0,不符合條件,所以清空列表
if maxsum > cursum:
pass
if maxsum < cursum:
maxsum = cursum
shortdict[maxsum] = templist[:]
if maxsum == cursum: #當最大和等於當前和的時候,比較二者對應子串行長度
if len(shortdict[maxsum]) > len(templist):
shortdict[maxsum] = templist[:]
return shortdict[maxsum]
在這裡,有個比較有意思的點:
假設我把某列表複製給了字典某鍵對應的值:tempdict[key] = templist, 然後再對該列表進行操作,則這個字典的鍵對應的值也會發生改變!因為直接使用等號+列表名是淺複製,只是把列表的位址複製給了字典,所以對列表的任何改變都會導致dict的改變!
我需要做的就是對列表進行深複製~ 深複製的方法很簡單:
方法1.
簡單列表的拷貝
已知乙個列表,求生成乙個新的列表,列表元素是原列表的複製
a=[1,2]
b=a[:]
這樣, 修改a對b沒有影響。修改b對a沒有影響。
方法2.
可以使用copy模組中的deepcopy函式。修改測試如下:
import copy
a=[1,2]
b=copy.deepcopy(a)
演算法 LeetCode刷題
given 1,3 2,6 8,10 15,18 return 1,6 8,10 15,18 關鍵就是a 1 b 0 也就是array i 1 1 array i 0 const merge array return array console.log merge 1,3 8,10 2,6 15,1...
leetcode刷題 動態規劃
動態規劃 英語 dynamic programming,簡稱 dp 是一種在數學 管理科學 電腦科學 經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。動態規劃背後的基...
leetcode刷題紀實(四)
給定乙個帶有頭結點 head 的非空單鏈表,返回鍊錶的中間結點。如果有兩個中間結點,則返回第二個中間結點。class solution return slow 這是快慢指標的經典解法,通過快慢指標移動速度的不同,來尋找到鍊錶的中間結點,而最好的速度比為2 1,這樣就可以使得當快指標到達鍊錶尾的時候,...