动态规划五部曲:
1、确定dp数组及其下标含义
dp[i][j]:以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串,编辑距离为dp[i][j]
2、确定递推式
word1[i-1]==word2[j-1]:不操作 dp[i][j] = dp[i-1][j-1]
word1[i-1]!=word2[j-1]
增 word1增加一个元素或者word2增加一个元素 使得word1[i-1]==word2[j-1]
dp[i][j] = dp[i-1][j]+1 或者dp[i][j] = dp[i][j-1]+1;
换 word1替换word1[i-1]使其与word2[j-1]相同,dp[i][j]=dp[i-1][j-1]+1
if(word1[i-1] == word2[j-1]){
dp[i][j] = dp[i-1][j-1];
}else{
dp[i][j]=min(dp[i-1][j],min(dp[i-1][j-1],dp[i][j-1]))+1;
3、初始化
for(int i = 0;i<=word1.size();i++){
dp[i][0] = i;
}
for(int j = 0;j<=word2.size();j++){
dp[0][j] = j;
}
4、确定遍历顺序
从左往右 从上往下
5、举例推导dp数组
"horse"
"ros"
dp:
0 1 2 3
1 1 2 3
2 2 1 2
3 2 2 2
4 3 3 2
5 4 4 3
题解:
class Solution {
public:
int minDistance(string word1, string word2) {
//dp[i][j]:以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串,编辑距离为dp[i][j]
//确定递推公式
//word1[i-1]==word2[j-1]:不操作 dp[i][j] = dp[i-1][j-1]
//word1[i-1]!=word2[j-1]
//增 word1增加一个元素或者word2增加一个元素 使得word1[i-1]==word2[j-1]
//dp[i][j] = dp[i-1][j]+1 或者dp[i][j] = dp[i][j-1]+1;
//换 word1替换word1[i-1]使其与word2[j-1]相同,dp[i][j]=dp[i-1][j-1]+1
//定义dp数组
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1));
//初始化dp
for(int i = 0;i<=word1.size();i++){
dp[i][0] = i;
}
for(int j = 0;j<=word2.size();j++){
dp[0][j] = j;
}
//计算dp
for(int i = 1;i<=word1.size();i++){
for(int j = 1;j<=word2.size();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],min(dp[i-1][j-1],dp[i][j-1]))+1;
}
}
}
return dp[word1.size()][word2.size()];
}
};