Day56 | 583. 两个字符串的删除操作, 72. 编辑距离
两个字符串的删除操作
LeetCode题目:https://leetcode.cn/problems/delete-operation-for-two-strings/
今天的两道题与昨天类似,DP数组的设定就是以i - 1结尾的word1字符串,和j - 1结尾的word2字符串相同需要的最小步数。因此同理可以进行初始化,当word1为0时候,那么Word2想要相同,就只能减去word2字符数量的字符。也就是进行j次操作。Word2为0的时候Word1也同理。因此初始化
for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;
同样,每个新的状态都由三种转移的可能,当i - 1 和j - 1的字符相同时,则说明当前匹配的字符不需要删除,因此从对角状态转移,即 dp[i][j] = dp[i - 1][j - 1]; 而当不匹配的时候,因为我要求得的是最少的操作数量,因此需要从i - 2 和 j - 1 以及i - 1和 j - 2 两种情况下获取最多的一个状态继承操作数量后,再额外进行一次删除操作即可。
代码如下:
class Solution {
public:
int minDistance(string word1, string word2) {
/* 以i - 1结尾的word1字符串,和j - 1结尾的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][j - 1] + 1, dp[i - 1][j] + 1);
}
}
}
return dp[word1.size()][word2.size()];
}
};
编辑距离
LeetCode题目:https://leetcode.cn/problems/edit-distance/
其实和删除操作类似,以i - 1结尾的word1字符串,和j - 1结尾的word2字符串相同需要的最小操作数。
之后进行递推,因为还是二维,所以递推的方式和之前相同,只有考虑情况不同。当i - 1 和 j - 1位置字符相等时,该位置不用操作,相当于i - 2结尾的s子序列在j - 2中出现过的操作数就是现在i - 1和 j - 1序列出现的个数。
当不相同的时候,则存在三种操作的可能,替换操作:将i - 1新增的字符进行一次操作,更换为 j - 1更新的字符串。删除/添加:当i - 2字符串和j - 1字符串存在操作数,在额外增加一个新字符后,可以直接将新增的i - 1字符删除。当i - 1和 j - 2时候同理。因此需要对比三种操作的最小值。
代码如下:
class Solution {
public:
int minDistance(string word1, string word2) {
/* 将下标到i-1的word1字符串,转换成下标到j-1的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(min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);
}
}
}
return dp[word1.size()][word2.size()];
}
};