LeetCode 72.Edit Distance (編輯距離)
阿新 • • 發佈:2018-11-28
題目:
給定兩個單詞 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')
思路:
如果沒有替換,只是簡單的增加和刪除的話,那麼可以用一個最長公共子序列去做,找到最長的公共字串,然後用len1+len2-2*公共子序列長度。
然而這裡有替換,有替換的話,情況就發生了變化,因為有時候替換一個比的上新增或刪除兩個。
定義狀態:dp[i][j]:第一個串的第i個位置與第二個串的第j個位置之前需要操作幾次達到相等。
之後,如果word1[i] = word2[j],如果相等的話,那麼就不用替換,也不要增刪,操作次數直接等於dp[i-1][j-1]。
如果不等於,需要考慮三種情況:
插入:在word1[i-1]的位置上插入word2[j-1],也就是說word1[0...i-1]=word2[0...j-1],dp[i][j]=dp[i][j-1]+1 替換:將word1[i-1]的值替換為word2[j-1]。dp[i][j]=dp[i-1][j-1]+1 刪除:將word1[i-1]的值刪除使word1[0...i-2]等價於word2[j-1], dp[i][j] = dp[i-1][j]+1
那麼轉移方程為:dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]))+1;
有一個錯誤的認識就是,如果一個長串和一個短串比較,如果刪只能刪當前較長的串,這種認識是錯誤的,舉個例子:
sma和uism,對這種情況,顯然必須刪除短串的最後一個字元,因為它礙著sm的匹配了。
AC C++ Solution:
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.size(), n = word2.size();
vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
// int dp[m+1][n+1];
for(int i = 0; i <= m; i++)
{
dp[i][0] = i;
}
for(int j = 0; j <= n; j++)
{
dp[0][j] = j;
}
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
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], min(dp[i][j-1], dp[i-1][j])) + 1;
}
}
}
return dp[m][n];
}
};