Leetcode--DP

32. Longest Valid Parentheses

dp[i] = dp[start - 1] + (i - start + 1): dp[i]表示到第i個位置為止的有效括號長度,dp[start - 1]表示在start之前的有效括號長度,i - start + 1表示從i到start中間的有效括號長度,start是從棧里pop出來與右括號相對應的左括號,i是當前右括號的下標
if s[i] == '(': stack.append(i),注意存放的是左括號下標
else: if stack: start = stack.pop() 如果遇到了右括號,且棧不為空,就從stack里pop出一個左括號的下標作為start
注意最后返回的是max(dp)

53. Maximum Subarray

假設我們已知第i步的global[i](全局最優)和local[i](局部最優),那么第i+1步的表達式是:
local[i+1]=Math.max(A[i], local[i]+A[i]),就是局部最優是一定要包含當前元素,所以不然就是上一步的局部最優local[i]+當前元素A[i](因為local[i]一定包含第i個元素,所以不違反條件),但是如果local[i]是負的,那么加上他就不如不需要的,所以不然就是直接用A[i];
global[i+1]=Math(local[i+1],global[i]),有了當前一步的局部最優,那么全局最優就是當前的局部最優或者還是原來的全局最優(所有情況都會被涵蓋進來,因為最優的解如果不包含當前元素,那么前面會被維護在全局最優里面,如果包含當前元素,那么就是這個局部最優)

70. Climbing Stairs

這道題目是求跑樓梯的可行解法數量。每一步可以爬一格或者兩個樓梯,可以發現,遞推式是f(n)=f(n-1)+f(n-2),也就是等于前一格的可行數量加上前兩格的可行數量。熟悉的朋友可能發現了,這個遞歸式正是[斐波那契數列]

注意當n==0時,也返回1. 初始化時,dp[0]=1, dp[1] = 2, 是從0和1開始,不是從1和2開始。
follow up是有沒有更好的解法: 有,O(logn),使用斐波那契的通項公式

general term formula
Follow up實現

91. Decode Ways

dp[i]存儲的是加入s中第i-1個元素后有多少種decode方式,所以dp[]初始化時的長度要比s多一位,并且使dp[0]=1

  • 注意,0只能出現在1或者2后邊,構成10,20,如果單獨出現的0,則無法解析
  • 如果字符s[i-1]不為0,則這個字符可以獨立地被解析,例如:1-9,dp[i] += dp[i-1]
  • 如果字符s[i-2:i]大于'09'且小于'27',證明i-1位字符和i-2位字符可以放在一起被解析,dp[i] += dp[i-2]
  • dp[i-2:i] < '27'這是按ASCII碼值來比較的,python中可以對字符串進行比較,都是先將其轉換為ASCII碼值。其中,大寫字母的值都小于小寫字母,同時('ab'<'abc')即空位的序數為所有字符最小
  • 最后返回dp[-1]

96. Unique Binary Search Trees

這道題在樹的分類里已經寫過了,但還是有些細節需要添加。

  • res數組要初始化n+1位,因為包括0在內了,并且res[0]和res[1]都要初始化為1,其余均為0
  • res[i]+= res[j]*res[i-j-1], res[j]代表i左邊的left branch數量,res[i-j-1]代表right branch數量。j是i左邊的node個數,i-j-1是i右邊的node個數,因為n是順序分解的,所以個數相同,生成的BST就相同。
  • 注意外層for循環i的范圍:for i in range(2, n+1):
  • 最后返回res[n]

95. Unique Binary Search Trees II

雖然在dp分類里,但其實更偏向于divide and conquer

  • 構建一個生產子樹的函數,參數為start, end,分別等于1和n
  • 在這個函數內,如果start>end,就返回[None], 括號里一定要有none, 如果start==end, 就返回[TreeNode(start)]
  • for i in range(start, end+1), end要加1
  • leftsubtree = self.generate(start, i-1), rightsubtree = self.generate(i+1, end)
  • 在for循環前要初始化res = []
  • 將左右子樹用兩個for循環排列組合起來,要先root = TreeNode(i), 每組合成功一個后就res.append(root)

120. Triangle

這道題之前也寫過了,需要注意的點有:

  • res初始化時的長度為triangle最后一行的長度再加1,加1是因為如果triangle里只有一行,那就超出了遞歸式里的索引范圍
  • 思路是將triangle reverse,然后針對每一行(倒序)里的每一個數字,更新res[i],等于當前數字,加上一組的min(res[i], res[i+1])
  • 最后返回res[0], 因為第一行只有一個數字

121. Best Time to Buy and Sell Stock

又是局部最優,全局最優方法。初始化local和res均為0, 先判斷數組是不是遞減的,如果是就返回0if sorted(prices) == prices[::-1]: return 0
若不是遞減的,針對數組中每一個數字,計算
local = max(0, local + prices[i+1] - prices[i]), res = max(res, local)

  • i的循環范圍是for i in range(len(prices)-1), 因為后邊有i+1
  • 更新local時,應該加上原來的Local, 和0比較是因為價格有可能是負數。
  • 為什么要加上原來的Local, 因為1,5,3,6, 1到6的距離是5,等于(5-1)+(3-5)+(6-3)

139. Word Break

針對動態規劃的思路:

  1. 決定存儲什么歷史信息以及用什么數據結構來存儲
  2. 遞推式,就是如何從存儲的歷史信息中得到當前結果
  3. 初始值的設定
    這道題,dp[i]表示的是在s中的前i-1個字符s[:i]是否存在wordDict里,初始化dp的長度要是s的長度加1,因為要存儲dp[0]=True
    雙重for循環,注意內層循環時j的范圍是for j in range(i, len(s)):, 從i開始到字符串結束。
    判斷條件if dp[i] and s[i:j+1] in wordDict: dp[j+1] = True
    dp[i]為真證明s的前i-1個字符存在里邊,如果s[i:j+1]也存在,我們就更新dp[j+1]為真
    最后返回dp[-1],d[7] is True because there is "code" in the dictionary that ends at the 7th index of "leetcode" AND d[3] is True

152. Maximum Product Subarray

和maximum sum subarray類似,只不過這道題是求最大乘積。方法也是先初始化maxlocal和res, 但這道題要再加一個minlocal,因為兩個很小的負數相乘之后可能會變成很大的整數。所以對nums進行遍歷時,遞推式里要再加一項對minlocal的更新。
并且要注意因為已經初始化了maxlocal, minlocal, res = nums[0], nums[0], nums[0], 所以for循環要從1開始。
在每次循環過程中:

maxcopy = maxlocal
maxlocal = max(maxlocal*nums[i], nums[i], minlocal*nums[i])
minlocal = min(maxcopy*nums[i], nums[i], minlocal*nums[i])
res = max(maxlocal, res)

要先將maxlocal復制一下,作為計算minloca時使用

62. Unique Paths

具體思路參考第161頁https://www.dropbox.com/s/d839bnp9lcroxmq/Sample_Interview_Questions_Set_16.pdf?dl=0

  • 需要注意的是,我們可以用二維數組代替一維數組。只需要對一維數組更新m次就可以。因為在二維數組中,每個方格所擁有的路徑數等于上邊方格?左邊方格。在一維數組中,每次更新時,當前方格就屬于上邊方格,所以只需要加上左邊方格就可。
  • 還有一點需要注意,內部循環從1開始. 這是因為第一列中每個方格的路徑數始終都是1
for i in range(m): 
       for j in range(1, n)```
- 初始化res[0] = 1,res的長度要和n一樣!!
#63. Unique Paths II
在上一題的基礎上增加了障礙,即有的方格為1時便不可通過。總體思想沒有變化,依然可以用一維數組代替二維數組。
- 這次內部循環不能從1開始,因為第一列的方格中有可能存在障礙,即值為1,所以每次循環都要做判斷:

if board[i][j] == 1:
res[j] = 0
elif j > 0:
res[j] += res[j-1]

- 依然需要初始化res[0] = 1,res的長度要和n一樣!!

#64. Minimum Path Sum
依然是從左上角到右下角,求最短路徑和。同樣使用一維數組,因為第一行的每個元素只能從左邊那個元素過來,所以grid第一行對應的一維數組:

for i in range(1, n):
res[i] = res[i-1] + grid[0][i]

然后對一維數組更新!!m-1次:

for i in range(1, m):
for j in range(n):
if j == 0:
res[j] = res[j] + grid[i][0]
else:
res[j] = min(res[j-1], res[j]) + grid[i][j]

- 當j==0時,證明我們在更新第一列,第一列的元素只能由上邊的元素過來,所以是上邊元素的值加上當前元素的值,res[j]就是上一行的第一列的元素。
- 當j!=0時,針對每個元素,它可以從上或左的元素得到,我們就在上和左元素中選一個最小值,再加上當前元素。上邊的元素就是res[j](因為此時還沒有更新res[j]), 左邊的元素就是res[j-1]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容