链接:0583.两个字符串的删除操作
参考:代码随想录
dp数组含义
dp[i][j]
:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。
递推公式
word1[i - 1]
与word2[j - 1]
相同的时候,dp[i][j] = dp[i - 1][j - 1]
word1[i - 1]
与word2[j - 1]
不相同的时候
word1[i - 1]
,最少操作次数为dp[i - 1][j] + 1
word2[j - 1]
,最少操作次数为dp[i][j - 1] + 1
word1[i - 1]
和word2[j - 1]
,操作的最少次数为dp[i - 1][j - 1] + 2
那最后当然是取最小值,所以当word1[i - 1]
与 word2[j - 1]
不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
因为dp[i - 1][j - 1] + 1
等于 dp[i - 1][j]
或 dp[i][j - 1]
,所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
初始化
从递推公式中,可以看出来,dp[i][0]
和 dp[0][j]
是一定要初始化的。
dp[i][0]
:word2为空字符串,以i-1为结尾的字符串word1要删除多少个元素,才能和word2相同呢,很明显dp[i][0] = i
。
dp[0][j]
的话同理
class Solution {
public:
int minDistance(string word1, string word2)
{
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
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()];
}
};
链接:0072.编辑距离
参考:代码随想录
dp数组
dp[i][j]
表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]
。
递推公式
在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:
if (word1[i - 1] == word2[j - 1])
// 不操作
if (word1[i - 1] != word2[j - 1])
// 增
// 删
// 换
if (word1[i - 1] == word2[j - 1])
那么说明不用任何编辑,dp[i][j]
就应该是 dp[i - 1][j - 1]
,即dp[i][j] = dp[i - 1][j - 1];
if (word1[i - 1] != word2[j - 1])
,此时就需要编辑了,如何编辑呢?
即dp[i][j] = dp[i - 1][j] + 1;
即dp[i][j] = dp[i][j - 1] + 1;
这里有同学发现了,怎么都是删除元素,添加元素去哪了。
word2添加一个元素,相当于word1删除一个元素,例如 word1 = “ad” ,word2 = “a”,word1删除元素’d’ 和 word2添加一个元素’d’,变成word1=“a”, word2=“ad”, 最终的操作数是一样!
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 - 1][j], dp[i][j - 1] }) + 1;
}
}
}
return dp[word1.size()][word2.size()];
}
};