Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word:
Insert a character(插入)
Delete a character(删除)
Replace a character(代替)
Example
Given word1 = "mart" and word2 = "karma", return 3
题解1 - 双序列动态规划
两个字符串⽐较,求最值,直接看似乎并不能直接找出解决⽅案,这时往往需要使⽤动态规划的思想寻找递推关系。使⽤双序列动态规划的通⽤做法,不妨定义 f[i][j] 为字符串1的前 i 个字符和字符串2的前 j 个字符的编辑距离,那么接下来寻找其递推关系。增删操作互为逆操作,即增或者删产⽣的步数都是⼀样的。故初始化时容易知道 f[0][j] = j, f[i][0] = i , 接下来探讨 f[i][j]和 f[i - 1][j - 1] 的关系,和 LCS 问题类似,我们分两种情况讨论,即 word1[i] == word2[j]与否,第⼀种相等的情况有:
1. i == j , 且有 word1[i] == word2[j] , 则由 f[i - 1][j - 1] -> f[i][j] 不增加任何操作,有 f[i][j] = f[i - 1][j - 1] .
2. i != j , 由于字符数不等,肯定需要增/删⼀个字符,但是增删 word1 还是 word2 是不知道的,
故可取其中编辑距离的较⼩值,即 f[i][j] = 1 + min{f[i - 1][j], f[i][j - 1]} .
第⼆种不等的情况有:
1. i == j , 有 f[i][j] = 1 + f[i - 1][j - 1] .
2. i != j , 由于字符数不等,肯定需要增/删⼀个字符,但是增删 word1 还是 word2 是不知道的,
故可取其中编辑距离的较⼩值,即 f[i][j] = 1 + min{f[i - 1][j], f[i][j - 1]} .
最后返回 f[len(word1)][len(word2)]
class Solution {
public:
int minDistance(string word1, string word2) {
if(word1.empty())
return word2.size();
if(word2.empty())
return word1.size();
int len1 = word1.size();
int len2 = word2.size();
vector<vector<int> > f(len1+1,vector<int>(len2+1, 0));
for(int i = 0; i <= len1; ++i)
f[i][0] = i;
for(int j = 0; j <= len2; ++j)
f[0][j] = j;
for(int i = 1; i <= len1; i++){
for(int j = 1; j <= len2; j++){
if(word1[i-1] == word2[j-1]){
f[i][j] = f[i-1][j-1];
}else
f[i][j] = 1 + min(f[i-1][j-1], min(f[i-1][j], f[i][j-1]));
}
}
return f[len1][len2];
}
};
或者为下面这个:
int minDistance(string word1, string word2) {
int len1=word1.length();
int len2=word2.length();
vector<vector<int>>dp(len1+1,vector<int>(len2+1));
for(int i=0;i<=len1;i++){
for(int j=0;j<=len2;j++){
if(i==0){
dp[i][j]=j; //如果 i=0 则需要插入j个字符
}else if(j==0){
dp[i][j]=i; //如果j=0则需要删除i个字符
}else if(word1[i-1]==word2[j-1]){ //如果字符相同则不做变换,等于这个字符之前的步数
dp[i][j]=dp[i-1][j-1];
}else{ //否则 就从插入,删除,修改中选择最小的 加 1
dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
}
return dp[len1][len2];
}