题目:
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:
a) Insert a character
b) Delete a character
c) Replace a character
在一个单词上可以有下面三种操作:
a、插入一个字符
b、删除一个字符
c、代替一个字符
思路:
动态规划法:设状态为f[i][j] ,表示A[0,i-1] 和B[0,j-1] 之间的最小编辑距离。设A[0,i-1] 的形式是str1c,B[0,j-1] 的形式是str2d,
1. 如果 c==d,则f[i][j]=f[i-1][j-1] ;
2. 如果 c!=d,
(a) 如果将c 替换成d,则f[i][j]=f[i-1][j-1]+1;
(b) 如果在c 后面添加一个d,则f[i][j]=f[i][j-1]+1;
(c) 如果将c 删除,则f[i][j]=f[i-1][j]+1;
代码:
class Solution {
public:
int minDistance(string word1, string word2)
{
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
{
int tmp = min(f[i-1][j] , f[i][j-1]);
f[i][j] = 1 + min(tmp , f[i-1][j-1]);
}
}
}
return f[len1][len2];
}
};
用一维数组优化存储空间:
class Solution {
public:
int minDistance(string word1, string word2)
{
int len1 = word1.size();
int len2 = word2.size();
if(len1 == 0 && len2 == 0)
return 0;
if(len1 < len2)
return minDistance(word2 , word1);//保证word2较短
vector<int> f(len2+1 , 0);
for(int i = 0 ; i <= len2 ; i++)
f[i] = i;
int pre = 0 ;额外用一个变量记录f[i-1][j-1]
int tmp = 0;
for(int j = 1 ; j <= len1 ; j++)
{
pre = f[0];//把上次的f[0]保存下来
f[0] = j;
for(int k = 1 ; k <= len2 ; k++)
{
tmp = f[k];//把上次的f[k]临时保存下来,以便下面赋给pre
if(word1[j-1] == word2[k-1]) //注意f[k]求的是0~k-1的字符的变化情况
f[k] = pre;
else
{
f[k] = min(f[k-1] , min(f[k] , pre)) + 1;
}
pre = tmp;//把上次的f[k]保存到pre中,以便下次比较
}
}
return f[len2];
}
};