day56
583.两个字符串的删除操作
题目链接:583. 两个字符串的删除操作
第一种思路:和求最长公共子序列代码相同,最终返回值不同,代码如下:
class Solution {
public:
int minDistance(string word1, string word2) {
// 1.参考最长公共子序列思路
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
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]+1;
}else{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
return (word1.size()+word2.size()-2*dp[word1.size()][word2.size()]);
}
};
常规思路
1.确定dp数组及下标含义
以下标为i-1结尾的word1和以下标为j-1为结尾的word2相同所需要删除的次数为$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[i-1]、删除word2[j-1]、和两个都删除,三者取最小值,即
dp[i][j] =min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+2)
,其实最后一种情况包含在前面的,可以去掉
3.初始化dp数组
$dp[i][0] = i$:对于空的word2数组,需要删除word1 i次才能使其相等
$dp[0][j]=j$:对于空的word1数组,需要删除word2 i次才能使其相等
4.确定遍历顺序
从前向后,从左向右
5.打印dp数组
class Solution {
public:
int minDistance(string word1, string word2) {
// // 1.参考最长公共子序列思路
// vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
// 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]+1;
// }else{
// dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
// }
// }
// }
// return (word1.size()+word2.size()-2*dp[word1.size()][word2.size()]);
// 2.本题常规思路
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
for( int i = 0; i <= word1.size(); i++){
dp[i][0] = i;
}
for( int j = 0; 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(dp[i-1][j]+1,dp[i][j-1]+1);
}
}
}
return dp[word1.size()][word2.size()];
}
};
72.编辑距离
题目链接:72. 编辑距离
1.确定dp数组及下标含义
将下标为i-1的单词word1转换为以下标j-1结尾的单词word2的最少操作数为$dp[i][j]$
2.递推公式
- word1[i-1] == word2[j-1]时,不进行操作,$dp[i][j] = dp[i-1][j-1]+1$
- word1[i-1] != word2[j-1]时,进行插入($dp[i][j-1]+1$,相当于对word2进行删除,逆向操作),删除($dp[i-1][j]+1$,对word1进行删除)替换($dp[i-1][j-1]+1$,修改了word1相当于在之前的基础上➕1),三者取最小值
3.初始化
$dp[i][0] = i;$ 相当于word2为空,删除i次
$dp[0][j]=j;$相当于word1为空,插入i次
4.遍历顺序
从左到右,从上到下
5.打印dp数组
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
for( int i = 0; i <= word1.size(); i++){
dp[i][0] = i;
}
for( int j = 0; 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(dp[i-1][j]+1,dp[i][j-1]+1);
dp[i][j] = min(dp[i][j],dp[i-1][j-1]+1);
}
}
}
return dp[word1.size()][word2.size()];
}
};