一:题目
二:上码
class Solution {
public:
/**
思路:题目给的是让求最值,那么首先就会想到的是动态规划,我们想得到答案的结果其实有多个的,但是我们是取最小的步数
动态规划 五步走:
1>:确定dp数组以及下标的含义
dp[i][j]表示的是 以下标i-1结尾的字符串word1,和以下标j-1结尾的word2,如果想要两个字符串相等
所需删除元素的最小个数。
这里我们定义的dp[i][j]中下标是比 字符串中的下标大一位。
2>:确定dp数组的状态递推公式
当word1[i-1] 和 word2[j-1] 相等的时候
dp[i][j] = dp[i-1][j-1];
当word1[j-1] 和 word2[j-1] 不相等的时候
我们可以删除word1[i-1] 那么的话 dp[i][j] = dp[i-1][j] + 1;
我们也可以删除word2[j-1] 那么的话 dp[i][j] = dp[i][j-1] + 1;
我们也可以同时删除 dp[i][j] = dp[i-1][j-1] + 2;
那么我们最终的取值的话 肯定是要取最小值
dp[i][j] = min(,,);
总结:我们在推导这个递推公式的时候 我们可以先假设好的情况 然后再去推断错误的情况
比方说 两个字符串中 前两个字符都是相等的 那么的话 dp[i][j] = dp[i-1][j-1] = 0
也就是说我们不需要进行什么操作,
当第三个字符不相等的时候,我们可以知道的是 这时候要做的事情就是要删除一个字符
我们可以删除任意一个字符串中的字符,那么的话,我们就是在删除那个字符的基础上,剩下的字符串,
与完整的字符串 也就是dp[i-1][j] 或则 dp[i][j-1] 在其基础上 + 1 因为我们多了一次删除操作
3>:确定dp数组的初始化
dp[i][0] 和 dp[0][j] 一定要初始化
因为dp[i][0]的话,也就是word2为空字符串 那么就是word1有几个字符串就要删除几个
4>确定dp数组的遍历顺序
哪个字符串在外层或者内层均可;
5>:举例验证
s e a
0 1 2 3
e 1 2 1 2
a 2 2 2 1 //这里为2的是指的是word1 删除的字符+ word2 删除的字符
t 3 3 3 2
**/
int minDistance(string word1, string word2) {
vector<vector<int> >dp(word1.size()+1,vector<int>(word2.size()+1,0));
for (int i = 1; i <= word1.size(); i++) {
dp[i][0] = i;
}
for (int j = 1; j <= word2.size(); j++) {
dp[0][j] = j;
}
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(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+2);
}
}
}
return dp[word1.size()][word2.size()];
}
};
状态转移方程就是将上个状态转移下来,也就是说 当前的状态对其没什么影响,但是如果什么加减操作的话,那也是在上个状态下进行的