目录
583. 两个字符串的删除操作
72. 编辑距离
583. 两个字符串的删除操作
题目链接:583. 两个字符串的删除操作
看到这一题就感觉很熟悉,实际上就是求最长公共子序列。
但这题出在这里的原因是为了给下一题做铺垫,所以还是换一种思路:
(1)dp[ i ][ j ] 表示 word1 前 i 个元素与 word2 前 j 个元素相同删除的最小步数
(2)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 ] + 2, min( dp[ i - 1 ][ j ] + 1, dp[ i ][ j - 1 ] + 1 ) );
但是,实际上 dp[ i - 1 ][ j - 1 ] + 2 == min( dp[ i - 1 ][ j ] + 1, dp[ i ][ j - 1 ] + 1 ),所以可以省略 dp[ i - 1 ][ j - 1 ] + 2 的情况。
(3)看初始化,列表格,根据(2)发现每个状态都是由上面或右面的状态转移来的,所以需要初始化第 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;
(4)外层遍历 word1,内层遍历 word2;
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][j-1] + 1);}}}return dp[word1.size()][word2.size()];}
};
72. 编辑距离
题目链接:72. 编辑距离
(1)dp[ i ][ j ] 表示将 word1 前 i 个元素,转换成 word2 前 j 个元素,所使用的最少操作数;
(2)如果 word1 比 word2 短,则一定要添加长度差值个元素才能完成转换,所以此时我们只要计算 word2 转换成 word1 所用的最少操作数,再加上长度差值,即为所求;
默认 word1 比 word2 长:
当 word1[ i - 1 ] == word2[ j - 1 ] 时:
无需操作,dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ];
当 word1[ i - 1 ] != word2[ j - 1 ] 时:
① 删除操作:dp[ i ][ j ] = dp[ i - 1 ][ j ];
② 替换操作:dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ];
③ 插入操作:dp[ i ][ j ] = dp[ i ][ j - 1 ];
那种操作数最少,就用哪种操作;
(3)dp[ i ][ 0 ] = i; dp[ 0 ][ j ] = j;
(4)外层遍历 word1,内层遍历 word2;
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], min(dp[i - 1][j], dp[i][j - 1])) + 1;}}}return dp[word1.size()][word2.size()];}
};