Problem
Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
You have the following 3 operations permitted on a word:
- Insert a character
- Delete a character
- Replace a character
Example1
Input: word1 = “horse”, word2 = “ros”
Output: 3
Explanation:
horse ->rorse (replace ‘h’ with ‘r’)
rorse -> rose (remove ‘r’)
rose -> ros(remove ‘e’)
Example2
Input: word1 = “intention”, word2 = “execution”
Output: 5
Explanation:
intention -> inention (remove ‘t’)
inention -> enention (replace ‘i’ with ‘e’)
enention -> exention (replace ‘n’ with ‘x’)
exention -> exection (replace ‘n’ with ‘c’)
exection -> execution (insert ‘u’)
Solution
dp[i][j]表示将word1的前i个字符变成word2的前j个字符的编辑距离,
对“dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。”的补充理解:
以 word1 为 “horse”,word2 为 “ros”,且 dp[5][3] 为例,即要将 word1的前 5 个字符转换为 word2的前 3 个字符,也就是将 horse 转换为 ros,因此有:
(1) dp[i-1][j-1],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 2 个字符 ro,然后将第五个字符 word1[4](因为下标基数以 0 开始) 由 e 替换为 s(即替换为 word2 的第三个字符,word2[2])
(2) dp[i][j-1],即先将 word1 的前 5 个字符 horse 转换为 word2 的前 2 个字符 ro,然后在末尾补充一个 s,即插入操作
(3) dp[i-1][j],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 3 个字符 ros,然后删除 word1 的第 5 个字符
class Solution {
public:
int minDistance(string word1, string word2) {
int n1 = word1.length();
int n2 = word2.length();
vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
//Fill 1st row
for(int i = 1;i<n2+1;++i)
dp[0][i] = dp[0][i-1] +1;
//Fill 1st col
for(int j = 1;j<n1+1;++j)
dp[j][0] = dp[j-1][1] + 1;
for(int i = 1;i<n1+1;++i)
for(int j = 1;j<n2+1;++j)
{
//we add one more row and one more col,so -1 is needed
if(word1[i-1] == word2[j-1])
dp[i][j] = dp[i-1][j-1];
else
{
dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;
}
}
return dp[n1][n2];
}
};
Ref
- https://leetcode-cn.com/problems/edit-distance/solution/zi-di-xiang-shang-he-zi-ding-xiang-xia-by-powcai-3/
- https://leetcode-cn.com/problems/edit-distance/solution/bian-ji-ju-chi-mian-shi-ti-xiang-jie-by-labuladong/