123. Leetcode 72. 编辑距离 (动态规划- 字符串系列)
?
步驟一、確定狀態(tài):
確定dp數(shù)組及下標含義 dp[i][j]表示word1[:i]的單詞與word2[:j]單詞之間的最小編輯距離
步驟二、推斷狀態(tài)方程:
在確定遞推公式的時候,首先要考慮清楚編輯的幾種操作,整理如下: if (word1[i - 1] == word2[j - 1]):
不操作
if (word1[i - 1] != word2[j - 1]):
插入操作 刪除操作 替換操作
步驟二、推斷狀態(tài)方程:
if (word1[i - 1] == word2[j - 1]) 那么說明不用任何編輯,
dp[i][j] 就應(yīng)該是 dp[i - 1][j - 1], 即dp[i][j] = dp[i - 1][j - 1];
步驟二、推斷狀態(tài)方程:
if (word1[i - 1] != word2[j - 1])
操作一:word1刪除一個元素,那么就是以下標i - 2為結(jié)尾的 word1 與 j-1為結(jié)尾的word2的最近編輯距離 再加上一個操作。 即 dp[i][j] = dp[i - 1][j] + 1;
操作二:word2刪除一個元素,那么就是以下標i - 1為結(jié)尾的 word1 與 j-2為結(jié)尾的word2的最近編輯距離 再加上一個操作。 即 dp[i][j] = dp[i][j - 1] + 1;
步驟二、推斷狀態(tài)方程:
word2添加一個元素,相當于word1刪除一個元素 dp數(shù)組如下圖所示意的:
步驟二、推斷狀態(tài)方程:
if (word1[i - 1] != word2[j - 1])
操作三:替換元素,word1替換word1[i - 1],使其與word2[j - 1] 相同,此時不用增加元素,那么以下標i-2為結(jié)尾的word1 與 j-2為 結(jié)尾的word2的最近編輯距離 加上一個替換元素的操作。
即dp[i][j]=dp[i-1][j-1]+1;
綜上,當 if (word1[i - 1] != word2[j - 1]) 時取最小的,即:dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
步驟三、規(guī)定初始條件:
初始條件:
全局初始化為0,而第一行和第一列需要初始化
步驟四、計算順序: 從如下四個遞推公式:
dp[i][j] = dp[i - 1][j - 1]
dp[i][j] = dp[i - 1][j - 1] + 1
dp[i][j] = dp[i][j - 1] + 1
dp[i][j] = dp[i - 1][j] + 1 可以看出dp[i][j]是依賴左方,上方和左上方元素的,如圖:
所以在dp矩陣中一定是從左到右從上到下去遍歷,dp數(shù)組從 [1,1]位置遍歷,外層遍歷word1, 內(nèi)層遍歷word2。
class Solution:def minDistance(self, word1: str, word2: str) -> int:# 異常判斷if len(word2) == 0:return len(word1)if len(word1) == 0:return len(word2)# 初始化dp = [[0 for _ in range(len(word2) + 1)] for _ in range(len(word1) + 1)]for i in range(len(word1) + 1):dp[i][0] = ifor j in range(len(word2) + 1):dp[0][j] = jfor i in range(1, len(word1) + 1):for j in range(1, len(word2) + 1):if word1[i-1] == word2[j-1]:dp[i][j] = dp[i-1][j-1]else:dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1return dp[-1][-1]?
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的123. Leetcode 72. 编辑距离 (动态规划- 字符串系列)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 122. Leetcode 647. 回
- 下一篇: 124. Leetcode 583. 两