文章目录
1. 两个字符串的删除操作
- LeetCode链接
给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。
每步 可以删除任意一个字符串中的一个字符。
示例1:
输入: word1 = “sea”, word2 = “eat”
输出: 2
解释: 第一步将 “sea” 变为 “ea” ,第二步将 "eat "变为 “ea”
示例2:
输入:word1 = “leetcode”, word2 = “etco”
输出:4
class Solution {
public:
int minDistance(string word1, string word2) {
// 通过删除单词来获取使得 word1和word2相同的最小步数
// 即求最长相同子序列
int l1 = word1.size(), l2 = word2.size();
// 1.dp[i][j] 表示 word1(0-i) 与 word2(0-j) 的最长相同子序列的长度
vector<vector<int>> dp(l1+1, vector<int>(l2+1, 0));
// 2.初始化, 都为0即可
// 3. 遍历
for(int i=1; i<=l1; i++){
for(int j=1; j<=l2; j++){
if(word1[i-1] == word2[j-1]){
dp[i][j] = max(dp[i-1][j-1]+1, dp[i][j]);
}else{
dp[i][j] = max(dp[i][j], max(dp[i-1][j], dp[i][j-1]));
}
}
}
return l1 + l2 - 2*dp[l1][l2];
}
};
2. 编辑距离
class Solution {
public:
int minDistance(string word1, string word2) {
// 1.dp[i][j] 表示以下标i-1为结尾的字符串word1 和 以j-1为结尾的字符串word2最近的编辑距离
// 2.确定递推公式
// word1[i] == word2[j] 不操作 dp[i][j] = dp[i-1][j-1]
// word1[i] != word2[j] 增 删 换
//操作1: word1删除一个元素,就是以i-2为结尾的word1与j-1为结尾的word2的最近编辑距离 + 1 dp[i][j] = dp[i-1][j]+1
//操作2: word2删除一个元素, 以j-2为结尾的word2与i-1为结尾的word1的最近编辑距离+ 1 dp[i][j] = dp[i][j-1]+1
// 因为word1或者word2删除一个元素,相当于另一个字符串添加一个元素,操作数一样,因此就不需要考虑添 增加元素的情况了
// 操作3: 替换元素 word1或者word2只需要替换一个元素就可以与对方匹配, dp[i][j] = dp[i-1][j-1] + 1
// 3. 初始化操作
// dp[i][j] 代表了 word1[i] 到 word2[j] 最短的编辑距离
// dp[i][0]表示下标为 i-1结尾的wrod1 和 空字符串word2的最短编辑距离,应该是i, dp[0][j]同理
int l1 = word1.size(), l2 = word2.size();
vector<vector<int>> dp(l1+1, vector<int>(l2+1, 0));
// 初始化
for(int i=0; i<=l1; i++) dp[i][0] = i;
for(int j=0; j<=l2; j++) dp[0][j] = j;
for(int i=1; i<=l1; i++){
for(int j=1; j<=l2; 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]+1); // 删除 和 替换中的最小的一个值
}
}
}
return dp[l1][l2];
}
};