583. 两个字符串的删除操作
求两个字符串的最长公共子序列,用两个字符串的长度减去两倍的最长公共子序列长度即为需要进行的最少次数的删除活动。
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 = 1; i <= word1.size(); i++) {for (int j = 1; j <= word2.size(); j++) {// dp整体向右下移动一个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]);}}}// 用两个字符串的长度和减去最长公共子序列的两倍即结果return word1.size()+word2.size()-2*dp[word1.size()][word2.size()];}
};
采用代码随想录的方法。一知半解。
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++) {// dp[i][j]:以i-1为结尾的字符串word1,// 和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。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()];}
};
72. 编辑距离
这个是一类问题,如果word1[i] == word2[j],可以不做修改,dp[i][j] = dp[i-1][j-1];如果 word1[i] != word2[j],则可以两个字符都退一位,替换一个字符;或者word1删除一位;或者word2删除一位;则递推公式为:
dp[i][j] = min({dp[i-1][j-1], dp[i][j-1], dp[i-1][j]}) + 1。删除和添加是一个意思,相当于进行一次操作,可以是删除也可以是增加。
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++) {// dp[i][j] 表示以下标i-1为结尾的字符串word1,// 和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][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], dp[i-1][j]}) + 1;}}}return dp[word1.size()][word2.size()];}
};