leetcode演算法刷題 四 動態規劃(二)

2022-07-20 18:51:12 字數 3063 閱讀 1162

又到了晚上,動態規劃,開刷!

題目的意思:給予乙個陣列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迴圈外新增了乙個變數minnumminnum = 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,這樣就可以使得當快指標到達鍊錶尾的時候,...