绝杀编辑距离
確定dp數組(dp table)以及下標的含義
dp[i][j] 表示以下標i-1為結尾的字符串word1,和以下標j-1為結尾的字符串word2,最近編輯距離為dp[i][j]。
確定遞推公式
在確定遞推公式的時候,首先要考慮清楚編輯的幾種操作,整理如下:
if (word1[i - 1] == word2[j - 1]) 不操作
if (word1[i - 1] != word2[j - 1]) 增 | 刪 | 換
也就是如上四種情況。
if (word1[i - 1] == word2[j - 1]) 那么說明不用任何編輯,dp[i][j] 就應該是 dp[i - 1][j- 1],即dp[i][j] = dp[i - 1][j - 1];
if (word1[i - 1] != word2[j - 1]),此時就需要編輯了,如何編輯呢?
操作一:word1增加一個元素,使其word1[i - 1]與word2[j - 1]相同,那么就是以下標i-2為結尾的word1 與 i-1為結尾的word2的最近編輯距離 加上一個增加元素的操作。
即 dp[i][j] = dp[i - 1][j] + 1;
操作二:word2添加一個元素,使其word1[i - 1]與word2[j - 1]相同,那么就是以下標i-1為結尾的word1 與j-2為結尾的word2的最近編輯距離 加上一個增加元素的操作。
即 dp[i][j] = dp[i][j - 1] + 1;
這里有同學發現了,怎么都是添加元素,刪除元素去哪了。
word2添加一個元素,相當于word1刪除一個元素,例如 word1 = “ad” ,word2 = “a”,word2添加一個元素d,也就是相當于word1刪除一個元素d,操作數是一樣!
操作三:替換元素,word1替換word1[i - 1],使其與word2[j -1]相同,此時不用增加元素,那么以下標i-2為結尾的word1 與 j-2為結尾的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;
dp數組如何初始化
在回顧一下dp[i][j]的定義。
dp[i][j] 表示以下標i-1為結尾的字符串word1,和以下標j-1為結尾的字符串word2,最近編輯距離為dp[i][j]。
那么dp[i][0] 和 dp[0][j] 表示什么呢?
dp[i][0] :以下標i-1為結尾的字符串word1,和空字符串word2,最近編輯距離為dp[i][0]。
那么dp[i][0]就應該是i,對word1里的元素全部做刪除操作,即:dp[i][0] = i;
同理dp[0][j] = j;
確定遍歷順序
從如下四個遞推公式:
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數組
以示例1,輸入:word1 = “horse”, word2 = "ros"為例,dp矩陣狀態圖如下:
總結
- 上一篇: 两个字符串的删除操作
- 下一篇: 回文子串个数