72. Edit Distance


思路:
dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数。
如果两个子串的最后一个字母相同,
word1[i] = word2[j]
的情况下:
D[i][j] = D[i - 1][j - 1]
否则,
word1[i] != word2[j]
我们将考虑替换最后一个字符使得他们相同:
D[i][j]=1+min(D[i−1][j],D[i][j−1],D[i−1][j−1])
解释:
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 个字符
#include<iostream>
#include<cstring>
using namespace std;
//dp[i][j]
int minDistance(string word1, string word2)
{
const int rowLen = word1.length() + 1;
const int colLen = word2.length() + 1;
int dp[rowLen][colLen];
dp[0][0] = 0;//初始化
for(int j=1;j<colLen;j++)
dp[0][j] = j;//一直插入
for(int i=1;i<rowLen;i++)
dp[i][0] = i;//一直删除
for(int i=1;i<rowLen;i++)//计算递推式
for(int j=1;j<colLen;j++)
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[rowLen-1][colLen-1];
}
int main()
{
string word1, word2;
cin>>word1>>word2;
cout<<minDistance(word1, word2)<<endl;
return 0;
}