583. 两个字符串的删除操作
1.本题和动态规划:1143.最长公共子序列 (opens new window)基本相同,只要求出两个字符串的最长公共子序列长度即可,那么除了最长公共子序列之外的字符都是必须删除的,最后用两个字符串的总长度减去两个最长公共子序列的长度就是删除的最少步数。
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
int result = 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]);
}
if (dp[i][j] > result)
result = dp[i][j];
}
}
return word1.size() + word2.size() - 2 * result;
}
};
2.动规,直接求删除次数。dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。关于递推数组简化部分我觉得随想录的解释还是有点问题,我觉得不是很好理解。
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
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(dp[i - 1][j], dp[i][j - 1]) + 1;
}
}
}
return dp.back().back();
}
};
72. 编辑距离
1.动规,dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。有了之前的铺垫,这一题就显得不那么难了,注意word2添加一个元素,相当于word1删除一个元素,巧妙的将增加元素操作转换为删除元素操作。(详细讲解还是看随想录录吧)
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
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({dp[i - 1][j] + 1, dp[i][j - 1] + 1,
dp[i - 1][j - 1] + 1});
}
}
}
return dp[word1.size()][word2.size()];
}
};
今日总结:编辑距离。