1.两个字符串的删除操作 题583
①dp数组含义
由于有两个数组比较,所以用二维数组dp。dp[i] [j]表示以i-1为结尾的word1和以j-1为结尾的word2达到相等需要删除的元素的个数。
②递推公式
两种情况,当word[i-1] == word2[j-1]时,有没有i-1为结尾和以j-1为结尾的都没关系,因为两个相同,所以不用删除操作,即dp[i] [j] = dp[i-1] [j-1]。
当word[i-1] != word2[j-1]时, 分三种情况:(1)删word1[i - 1],最少操作次数为dp[i - 1] [j] + 1;
(2)删word2[j - 1],最少操作次数为dp[i] [j - 1] + 1;
(3)同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1] [j - 1] + 2。
取三种情况的最小值。
③初始化与遍历顺序
dp[i] [0]:word2为空字符串,以i-1为结尾的字符串word1要删除多少个元素,才能和word2相同呢,很明显dp[i] [0] = i。遍历顺序看递推公式的方向。
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()];
}
};
2.编辑距离 题72
①dp数组含义
两个数组比较,所以dp数组为二维数组。
dp[i] [j]表示为以i-1结尾的word1和以j-1为结尾的word2的最少操作次数。
②递推公式
两种情况
if (word1[i - 1] == word2[j - 1])
不操作
if (word1[i - 1] != word2[j - 1])
增
删
换
word1[i - 1] == word2[j - 1]时,不用操作,所以dp[i] [j] = dp[i - 1] [j - 1];
word1[i - 1] != word2[j - 1]时:
③初始化
dp[i] [0] 表示以i-1结尾字符串1和空字符串的最小操作数,要么删除字符串i个字符变成空字符串,要么字符串2加上相同的i个字符串1的字符,所以都是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,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({(int)dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1});
}
}
}
return dp[word1.size()][word2.size()];
}
};