菜鸟LeetCode-动态规划
動態規劃
目錄
- 動態規劃
- 一、動態規劃的思想
- 二、動態規劃適用的情況
- 三、動態規劃模板步驟
- 四、相關練習
- 300. 最長上升子序列
- 674. 最長連續遞增序列
- 5. 最長回文子串
- 516. 最長回文子序列
- 72. 編輯距離
- 198. 打家劫舍
- 213. 打家劫舍 II
一、動態規劃的思想
若要解一個給定問題,我們需要解其不同部分(即子問題),再根據子問題的解以得出原問題的解。動態規劃往往用于優化遞歸問題,例如斐波那契數列,如果運用遞歸的方式來求解會重復計算很多相同的子問題,利用動態規劃的思想可以減少計算量。
動態規劃法僅僅解決每個子問題一次,具有天然剪枝的功能,從而減少計算量,
一旦某個給定子問題的解已經算出,則將其記憶化存儲,以便下次需要同一個子問題解之時直接查表。
二、動態規劃適用的情況
一般用于求最值問題。
適用動態規劃方法求解,問題需要滿足三個要素:
- 具有重疊子結構
- 具有最優子結構
- 狀態轉移方程
三、動態規劃模板步驟
-
確定動態規劃狀態
-
寫出狀態轉移方程(畫出狀態轉移表)
-
考慮初始化條件
這是決定整個程序能否跑通的重要步驟,當我們確定好狀態轉移方程,我們就需要考慮一下邊界值,邊界值考慮主要又分為三個地方:
- dp數組整體的初始值
- dp數組(二維)i=0和j=0的地方
- dp存放狀態的長度,是整個數組的長度還是數組長度加一,這點需要特別注意。
- 考慮輸出狀態
主要有以下三種形式,對于具體問題,我們一定要想清楚到底dp數組里存儲的是哪些值,最后我們需要的是數組中的哪些值:
- 返回dp數組中最后一個值作為輸出,一般對應二維dp問題。
- 返回dp數組中最大的那個數字,一般對應記錄最大值問題。
- 返回保存的最大值,一般是Maxval=max(Maxval,dp[i])這樣的形式。
- 考慮對時間,空間復雜度的優化(Bonus)
總結幾種Python常用的初始化方法
- 對于產生一個全為1,長度為n的數組:
- 對于產生一個全為0,長度為m,寬度為n的二維矩陣:
四、相關練習
300. 最長上升子序列
給定一個無序的整數數組,找到其中最長上升子序列的長度。
示例:
輸入: [10,9,2,5,3,7,101,18]
輸出: 4
解釋: 最長的上升子序列是 [2,3,7,101],它的長度是 4。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
674. 最長連續遞增序列
給定一個未經排序的整數數組,找到最長且連續的的遞增序列,并返回該序列的長度。
示例 1:
輸入: [1,3,5,4,7]
輸出: 3
解釋: 最長連續遞增序列是 [1,3,5], 長度為3。
盡管 [1,3,5,7] 也是升序的子序列, 但它不是連續的,因為5和7在原數組里被4隔開。
示例 2:
輸入: [2,2,2,2,2]
輸出: 1
解釋: 最長連續遞增序列是 [2], 長度為1。
注意:數組長度不會超過10000。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
5. 最長回文子串
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: “babad”
輸出: “bab”
注意: “aba” 也是一個有效答案。
示例 2:
輸入: “cbbd”
輸出: “bb”
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
516. 最長回文子序列
給定一個字符串 s ,找到其中最長的回文子序列,并返回該序列的長度。可以假設 s 的最大長度為 1000 。
示例 1:
輸入:
“bbbab”
輸出:
4
一個可能的最長回文子序列為 “bbbb”。
示例 2:
輸入:
“cbbd”
輸出:
2
一個可能的最長回文子序列為 “bb”。
提示:
1 <= s.length <= 1000
s 只包含小寫英文字母
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/longest-palindromic-subsequence
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
72. 編輯距離
給你兩個單詞 word1 和 word2,請你計算出將 word1 轉換成 word2 所使用的最少操作數 。
你可以對一個單詞進行如下三種操作:
插入一個字符
刪除一個字符
替換一個字符
示例 1:
輸入:word1 = “horse”, word2 = “ros”
輸出:3
解釋:
horse -> rorse (將 ‘h’ 替換為 ‘r’)
rorse -> rose (刪除 ‘r’)
rose -> ros (刪除 ‘e’)
示例 2:
輸入:word1 = “intention”, word2 = “execution”
輸出:5
解釋:
intention -> inention (刪除 ‘t’)
inention -> enention (將 ‘i’ 替換為 ‘e’)
enention -> exention (將 ‘n’ 替換為 ‘x’)
exention -> exection (將 ‘n’ 替換為 ‘c’)
exection -> execution (插入 ‘u’)
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/edit-distance
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
198. 打家劫舍
難度:Hard(面試常考)
你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數數組,計算你 不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。
示例 1:
輸入:[1,2,3,1]
輸出:4
解釋:偷竊 1 號房屋 (金額 = 1) ,然后偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入:[2,7,9,3,1]
輸出:12
解釋:偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接著偷竊 5 號房屋 (金額 = 1)。偷竊到的最高金額 = 2 + 9 + 1 = 12 。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 400
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/house-robber
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
213. 打家劫舍 II
你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第一個房屋和最后一個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例 1:
輸入: [2,3,2]
輸出: 3
解釋: 你不能先偷竊 1 號房屋(金額 = 2),然后偷竊 3 號房屋(金額 = 2), 因為他們是相鄰的。
示例 2:
輸入: [1,2,3,1]
輸出: 4
解釋: 你可以先偷竊 1 號房屋(金額 = 1),然后偷竊 3 號房屋(金額 = 3)。偷竊到的最高金額 = 1 + 3 = 4 。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/house-robber-ii
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
感想:
最難的還是狀態轉移方程的定義!
參考:
1、動態規劃詳解(修訂版)
2、動態規劃
總結
以上是生活随笔為你收集整理的菜鸟LeetCode-动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 恶梦护士 asa_噩梦就是JSON日期。
- 下一篇: Grizzly