@@ -79,6 +79,23 @@ class Solution:
7979 return min (dp)
8080```
8181
82+ ``` Python
83+ class Solution :
84+ def minimumTotal (self , triangle : List[List[int ]]) -> int :
85+ result = triangle
86+ count = 0
87+ for line in result:
88+ line[0 ] += count
89+ count = line[0 ]
90+ for i in range (1 , len (triangle)):
91+ for j in range (1 , len (triangle[i])):
92+ if j >= len (triangle[i- 1 ]):
93+ result[i][j] += result[i- 1 ][j- 1 ]
94+ else :
95+ result[i][j] += min (result[i- 1 ][j- 1 ], result[i- 1 ][j])
96+ return min (result[- 1 ])
97+ ```
98+
8299## 递归和动规关系
83100
84101递归是一种程序的实现方式:函数的自我调用
@@ -162,6 +179,22 @@ class Solution:
162179 return dp[- 1 ]
163180```
164181
182+ ``` Python
183+ class Solution :
184+ def minPathSum (self , grid : List[List[int ]]) -> int :
185+ m = len (grid)
186+ n = len (grid[0 ])
187+ result = grid
188+ for i in range (1 , m):
189+ result[i][0 ] += result[i- 1 ][0 ]
190+ for j in range (1 , n):
191+ result[0 ][j] += result[0 ][j- 1 ]
192+ for i in range (1 , m):
193+ for j in range (1 , n):
194+ result[i][j] += min (result[i- 1 ][j], result[i][j- 1 ])
195+ return result[- 1 ][- 1 ]
196+ ```
197+
165198### [ unique-paths] ( https://leetcode-cn.com/problems/unique-paths/ )
166199
167200> 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
@@ -184,6 +217,16 @@ class Solution:
184217 return dp[- 1 ]
185218```
186219
220+ ``` Python
221+ class Solution :
222+ def uniquePaths (self , m : int , n : int ) -> int :
223+ result = [[1 ] * n for _ in range (m)]
224+ for i in range (1 , m):
225+ for j in range (1 , n):
226+ result[i][j] = result[i- 1 ][j] + result[i][j- 1 ]
227+ return result[- 1 ][- 1 ]
228+ ```
229+
187230### [ unique-paths-ii] ( https://leetcode-cn.com/problems/unique-paths-ii/ )
188231
189232> 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
@@ -210,6 +253,31 @@ class Solution:
210253 return dp[- 1 ]
211254```
212255
256+ ``` Python
257+ class Solution :
258+ def uniquePathsWithObstacles (self , obstacleGrid : List[List[int ]]) -> int :
259+ if obstacleGrid[0 ][0 ]:
260+ return 0
261+ m = len (obstacleGrid)
262+ n = len (obstacleGrid[0 ])
263+ result = [[0 ] * n for _ in range (m)]
264+ result[0 ][0 ] = 1
265+ for i in range (1 , m):
266+ if not obstacleGrid[i][0 ]:
267+ result[i][0 ] = result[i- 1 ][0 ]
268+ for j in range (1 , n):
269+ if not obstacleGrid[0 ][j]:
270+ result[0 ][j] = result[0 ][j- 1 ]
271+
272+ for i in range (1 , m):
273+ for j in range (1 , n):
274+ if obstacleGrid[i][j]:
275+ result[i][j] = 0
276+ else :
277+ result[i][j] = result[i- 1 ][j] + result[i][j- 1 ]
278+ return result[- 1 ][- 1 ]
279+ ```
280+
213281## 2、序列类型(40%)
214282
215283### [ climbing-stairs] ( https://leetcode-cn.com/problems/climbing-stairs/ )
@@ -229,6 +297,18 @@ class Solution:
229297 return step1
230298```
231299
300+ ``` Python
301+ class Solution :
302+ def climbStairs (self , n : int ) -> int :
303+ if n == 1 :
304+ return n
305+ result = [1 ] * n
306+ result[1 ] = 2
307+ for i in range (2 , n):
308+ result[i] = result[i- 1 ] + result[i- 2 ]
309+ return result[- 1 ]
310+ ```
311+
232312### [ jump-game] ( https://leetcode-cn.com/problems/jump-game/ )
233313
234314> 给定一个非负整数数组,你最初位于数组的第一个位置。
@@ -265,6 +345,19 @@ class Solution:
265345 return True
266346```
267347
348+ ``` Python
349+ class Solution :
350+ def canJump (self , nums : List[int ]) -> bool :
351+ max_jump = 0
352+ length = len (nums)
353+ for i in range (length):
354+ if max_jump >= i:
355+ max_jump = max (max_jump, i + nums[i])
356+ if max_jump >= length - 1 :
357+ return True
358+ return False
359+ ```
360+
268361### [ jump-game-ii] ( https://leetcode-cn.com/problems/jump-game-ii/ )
269362
270363> 给定一个非负整数数组,你最初位于数组的第一个位置。
@@ -293,6 +386,18 @@ class Solution:
293386 return min_step
294387```
295388
389+ ``` Python
390+ class Solution :
391+ def jump (self , nums : List[int ]) -> int :
392+ max_jump, step, end = 0 , 0 , 0
393+ for i in range (len (nums)- 1 ):
394+ max_jump = max (max_jump, i+ nums[i])
395+ if i == end:
396+ step += 1
397+ end = max_jump
398+ return step
399+ ```
400+
296401### [ palindrome-partitioning-ii] ( https://leetcode-cn.com/problems/palindrome-partitioning-ii/ )
297402
298403> 给定一个字符串 _ s_ ,将 _ s_ 分割成一些子串,使每个子串都是回文串。
@@ -330,6 +435,24 @@ class Solution:
330435 return dp_min[- 1 ]
331436```
332437
438+ ``` Python
439+ class Solution :
440+ def minCut (self , s : str ) -> int :
441+ n = len (s)
442+ if n < 2 :
443+ return 0
444+ result = [n] * n
445+ result[0 ] = 0
446+ for i in range (1 , n):
447+ if s[:i+ 1 ] == s[:i+ 1 ][::- 1 ]:
448+ result[i] = 0
449+ continue
450+ for j in range (i):
451+ if s[j+ 1 :i+ 1 ] == s[j+ 1 :i+ 1 ][::- 1 ]:
452+ result[i] = min (result[i], result[j]+ 1 )
453+ return result[- 1 ]
454+ ```
455+
333456### [ longest-increasing-subsequence] ( https://leetcode-cn.com/problems/longest-increasing-subsequence/ )
334457
335458> 给定一个无序的整数数组,找到其中最长上升子序列的长度。
@@ -369,6 +492,23 @@ class Solution:
369492 return len (seq)
370493```
371494
495+ ``` Python
496+ class Solution :
497+ def lengthOfLIS (self , nums : List[int ]) -> int :
498+ result = [nums[0 ]]
499+ length = len (nums)
500+ for i in range (1 , length):
501+ if nums[i] > result[- 1 ]:
502+ result.append(nums[i])
503+ continue
504+ if nums[i] < result[- 1 ]:
505+ for j in range (len (result)):
506+ if nums[i] <= result[j]:
507+ result[j] = nums[i]
508+ break
509+ return len (result)
510+ ```
511+
372512### [ word-break] ( https://leetcode-cn.com/problems/word-break/ )
373513
374514> 给定一个** 非空** 字符串 * s* 和一个包含** 非空** 单词列表的字典 * wordDict* ,判定 * s* 是否可以被空格拆分为一个或多个在字典中出现的单词。
@@ -390,6 +530,22 @@ class Solution:
390530
391531```
392532
533+ ``` Python
534+ class Solution :
535+ def wordBreak (self , s : str , wordDict : List[str ]) -> bool :
536+ length = len (s)
537+ result = [False ] * length
538+ for i in range (length):
539+ if s[:i+ 1 ] in wordDict:
540+ result[i] = True
541+ continue
542+ for j in range (i+ 1 ):
543+ if result[j] and s[j+ 1 :i+ 1 ] in wordDict:
544+ result[i] = True
545+ break
546+ return result[- 1 ]
547+ ```
548+
393549小结
394550
395551常见处理方式是给 0 位置占位,这样处理问题时一视同仁,初始化则在原来基础上 length+1,返回结果 f[ n]
@@ -437,6 +593,21 @@ class Solution:
437593 return dp[- 1 ]
438594```
439595
596+ ``` Python
597+ class Solution :
598+ def longestCommonSubsequence (self , text1 : str , text2 : str ) -> int :
599+ m = len (text1) + 1
600+ n = len (text2) + 1
601+ result = [[0 ]* n for _ in range (m)]
602+ for i in range (1 , m):
603+ for j in range (1 , n):
604+ if text1[i- 1 ] == text2[j- 1 ]:
605+ result[i][j] = result[i- 1 ][j- 1 ] + 1
606+ else :
607+ result[i][j] = max (result[i- 1 ][j], result[i][j- 1 ])
608+ return result[- 1 ][- 1 ]
609+ ```
610+
440611### [ edit-distance] ( https://leetcode-cn.com/problems/edit-distance/ )
441612
442613> 给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数
@@ -476,6 +647,28 @@ class Solution:
476647 return dp[- 1 ]
477648```
478649
650+ ``` Python
651+ class Solution :
652+ def minDistance (self , word1 : str , word2 : str ) -> int :
653+ m = len (word1)
654+ n = len (word2)
655+ if not m* n:
656+ return m+ n
657+ m, n = m + 1 , n + 1
658+ result = [[0 ]* n for _ in range (m)]
659+ for i in range (m):
660+ result[i][0 ] = i
661+ for j in range (n):
662+ result[0 ][j] = j
663+ for i in range (1 , m):
664+ for j in range (1 , n):
665+ if word1[i- 1 ] == word2[j- 1 ]:
666+ result[i][j] = result[i- 1 ][j- 1 ]
667+ else :
668+ result[i][j] = min (result[i- 1 ][j- 1 ], result[i- 1 ][j], result[i][j- 1 ]) + 1
669+ return result[- 1 ][- 1 ]
670+ ```
671+
479672说明
480673
481674> 另外一种做法:MAXLEN(a,b)-LCS(a,b)
@@ -504,6 +697,19 @@ class Solution:
504697 return - 1 if dp[amount] == float (' inf' ) else dp[amount]
505698```
506699
700+ ``` Python
701+ class Solution :
702+ def coinChange (self , coins : List[int ], amount : int ) -> int :
703+ result = [float (" inf" )] * (amount+ 1 )
704+ result[0 ] = 0
705+ for i in range (1 , amount+ 1 ):
706+ for j in range (len (coins)):
707+ if i >= coins[j]:
708+ result[i] = min (result[i], result[i- coins[j]]+ 1 )
709+ if result[- 1 ] == float (" inf" ):
710+ return - 1
711+ return result[- 1 ]
712+ ```
507713
508714### [ backpack] ( https://www.lintcode.com/problem/backpack/description )
509715
@@ -529,6 +735,10 @@ class Solution:
529735
530736```
531737
738+ ``` Python
739+
740+ ```
741+
532742### [ backpack-ii] ( https://www.lintcode.com/problem/backpack-ii/description )
533743
534744> 有 ` n ` 个物品和一个大小为 ` m ` 的背包. 给定数组 ` A ` 表示每个物品的大小和数组 ` V ` 表示每个物品的价值.
@@ -556,6 +766,10 @@ class Solution:
556766
557767```
558768
769+ ``` Python
770+
771+ ```
772+
559773## 补充
560774
561775### [ maximum-product-subarray] ( https://leetcode-cn.com/problems/maximum-product-subarray/ )
@@ -588,6 +802,10 @@ class Solution:
588802 return max_product
589803```
590804
805+ ``` Python
806+
807+ ```
808+
591809### [ decode-ways] ( https://leetcode-cn.com/problems/decode-ways/ )
592810
593811> 1 到 26 分别对应 a 到 z,给定输入数字串,问总共有多少种译码方法
@@ -611,6 +829,10 @@ class Solution:
611829 return dp_1
612830```
613831
832+ ``` Python
833+
834+ ```
835+
614836### [ best-time-to-buy-and-sell-stock-with-cooldown] ( https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ )
615837
616838> 给定股票每天的价格,每天可以买入卖出,买入后必须卖出才可以进行下一次购买,卖出后一天不可以购买,问可以获得的最大利润
@@ -629,6 +851,23 @@ class Solution:
629851 return max (buy, buy_then_nothing, sell, sell_then_nothing)
630852```
631853
854+ ``` Python
855+ class Solution :
856+ def maxProfit (self , prices : List[int ]) -> int :
857+ n = len (prices)
858+ if n < 2 :
859+ return 0
860+ buy = [0 ] * n
861+ sell = [0 ] * n
862+ sell_s = [0 ] * n
863+ buy[0 ] = - prices[0 ]
864+ for i in range (1 , n):
865+ buy[i] = max (buy[i- 1 ], sell[i- 1 ] - prices[i])
866+ sell_s[i] = buy[i- 1 ] + prices[i]
867+ sell[i] = max (sell_s[i- 1 ], sell[i- 1 ])
868+ return max (sell[- 1 ], sell_s[- 1 ])
869+ ```
870+
632871### [ word-break-ii] ( https://leetcode-cn.com/problems/word-break-ii/ )
633872
634873> 给定字符串和可选的单词列表,求字符串所有的分割方式
@@ -671,6 +910,10 @@ class Solution:
671910 return result
672911```
673912
913+ ``` Python
914+
915+ ```
916+
674917### [ burst-balloons] ( https://leetcode-cn.com/problems/burst-balloons/ )
675918
676919> n 个气球排成一行,每个气球上有一个分数,每次戳爆一个气球得分为该气球分数和相邻两气球分数的乘积,求最大得分
@@ -697,6 +940,10 @@ class Solution:
697940 return dp[- 1 ][n]
698941```
699942
943+ ``` Python
944+
945+ ```
946+
700947
701948
702949## 练习
0 commit comments