[leetcode] 72. 编辑距离(二维动态规划)
72. 編輯距離
再次驗證leetcode的評判機有問題啊!同樣的代碼,第一次提交超時,第二次提交就通過了!
此題用動態規劃解決。
這題一開始還真難到我了,琢磨半天沒有思路。于是乎去了網上喵了下題解看到了動態規劃4個字就趕緊回來了。
腦海中浮現了兩個問題:
為什么能用動態規劃呢?用動態規劃怎么解?
先描述狀態吧:
f[i][j]表示word1中的[0,i] 與 word2中[0,j]的最少操作數。
實際上這時候就能看出來了,當一個狀態計算完成時,即一個狀態的操作方案(決策)確定時,不影響后面狀態的最優決策。即滿足動態規劃要求的無后效性,否則不能用動規來解決啦,因為要涉及到回溯修改前面的決策。也就是滿足兩個條件:1. 重疊子問題 2.最優子結構
動態規劃原理
雖然已經用動態規劃方法解決了上面兩個問題,但是大家可能還跟我一樣并不知道什么時候要用到動態規劃。總結一下上面的斐波拉契數列和鋼條切割問題,發現兩個問題都涉及到了重疊子問題,和最優子結構。
①最優子結構
用動態規劃求解最優化問題的第一步就是刻畫最優解的結構,如果一個問題的解結構包含其子問題的最優解,就稱此問題具有最優子結構性質。因此,某個問題是否適合應用動態規劃算法,它是否具有最優子結構性質是一個很好的線索。使用動態規劃算法時,用子問題的最優解來構造原問題的最優解。因此必須考查最優解中用到的所有子問題。
②重疊子問題
在斐波拉契數列和鋼條切割結構圖中,可以看到大量的重疊子問題,比如說在求fib(6)的時候,fib(2)被調用了5次,在求cut(4)的時候cut(0)被調用了4次。如果使用遞歸算法的時候會反復的求解相同的子問題,不停的調用函數,而不是生成新的子問題。如果遞歸算法反復求解相同的子問題,就稱為具有重疊子問題(overlapping subproblems)性質。在動態規劃算法中使用數組來保存子問題的解,這樣子問題多次求解的時候可以直接查表不用調用函數遞歸。
顯然,狀態轉移方程也就出來了:
f[i][j] 的計算分為兩種情況:
那初始條件呢?當一方為空時,最少操作數就是另一個word的size了
for (int i = 0; i <= m; i++) {f[i][0] = i;}for (int j = 0; j <= n; j++) {f[0][j] = j;}1A代碼
class Solution {public int minDistance(String word1, String word2) {int m = word1.length();int n = word2.length();if (m == 0) {return n;}if (n == 0) {return m;}int[][] f = new int[m + 1][n + 1];for (int i = 0; i <= m; i++) {f[i][0] = i;}for (int j = 0; j <= n; j++) {f[0][j] = j;}for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (word1.charAt(i - 1) == word2.charAt(j - 1)) {f[i][j] = f[i - 1][j - 1];} else {f[i][j] = Collections.min(Arrays.asList(f[i - 1][j - 1], f[i - 1][j], f[i][j - 1])) + 1;}}}return f[m][n];} }轉載于:https://www.cnblogs.com/acbingo/p/9369297.html
總結
以上是生活随笔為你收集整理的[leetcode] 72. 编辑距离(二维动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj1328 区间贪心 挑战程序设计竞
- 下一篇: weblogic漏洞复现(CVE-202