代码随想录 (programmercarl.com)
583. 两个字符串的删除操作
本题和LC115.不同的子序列 相比,其实就是两个字符串都可以删除了,情况虽说复杂一些,但整体思路是不变的。
1.dp数组及下标含义
dp[i][j]:表示使以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t相同的最小操作步数为dp[i][j]。
2.递推公式
- if (s[i - 1] == t[j - 1])
- 表示这两个字符串这两个元素是相同的,所以在计算最小操作步数的时候考虑这两个元素和不考虑这两个元素是一样的,即dp[i][j] = dp[i - 1][j - 1];
- if (s[i - 1] != t[j - 1])
- 此时需要删除该元素,可以选择删除s里面的元素(dp[i - 1][j] + 1)或者t里面的元素(dp[i][j - 1] + 1),或者把这两个元素都删了(dp[i - 1][j - 1] + 2)。
- 在dp[i [j - 1]的基础上,如果需要删除s中的元素,则dp[i][j - 1] = dp[i - 1][j - 1] + 1,代入到dp[i][j - 1] + 1之后,变为dp[i - 1][j - 1] + 2,所以上面三种情况可以进一步简化为两种,即dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
3.初始化
dp[0][j]表示以下标-1结尾的字符串s(空串)和以下标为j - 1结尾的字符串t相同的最小步数就是删除t中的所有元素,即初始化为j。
同理,dp[i][0]表示使以下标i - 1结尾的字符串s和空串相同的最小操作次数为i。
4.遍历顺序
遍历顺序为从上到下,从左到右。
class Solution {public int minDistance(String word1, String word2) {int[][] dp = new int[word1.length() + 1][word2.length() + 1];for (int i = 0; i <= word1.length(); i++) {dp[i][0] = i;}for (int j = 0; j <= word2.length(); j++) {dp[0][j] = j;}for (int i = 1; i <= word1.length(); i++) {for (int j = 1; j <= word2.length(); j++) {if (word1.charAt(i - 1) == word2.charAt(j - 1)){dp[i][j] = dp[i - 1][j - 1];}else {dp[i][j] = Math.min(dp[i - 1][j] + 1, Math.min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 2));}}}return dp[word1.length()][word2.length()];}
}
72.编辑距离
注意:word1和word2都可以进行改变,最终目的就是使得word1==word2
1.dp数组及下标含义
dp[i][j]:表示以下标i - 1为结尾的字符串word1,和以下标j - 1为结尾的字符串word2,最近编辑距离为dp[i][j]。
2.递推公式
1)if (word1[i - 1] == word2[j - 1])
不操作:dp[i][j] = dp[i - 1][j - 1];
2)if (word1[i - 1] != word2[j - 1])
增:增其实是删的逆过程,比如word1[a,b], word2[a],可以考虑删除word1中的b,也可以考虑增加word2中的b,所以操作次数和删除相同。
删:dp[i][j] = dp[i - 1][j] + 1、dp[i][j] = dp[i][j - 1] + 1
换:dp[i][j] = dp[i - 1][j - 1] + 1
3.初始化
根据dp[i][j]定义可知,dp[i][0] = i;dp[0][j] = j
4.遍历顺序
遍历顺序为从上到下,从左到右。
class Solution {public int minDistance(String word1, String word2) {int[][] dp = new int[word1.length() + 1][word2.length() + 1];for (int i = 0; i <= word1.length(); i++) {dp[i][0] = i;}for (int j = 0; j <= word2.length(); j++) {dp[0][j] = j;}for (int i = 1; i <= word1.length(); i++) {for (int j = 1; j <= word2.length(); j++) {if(word1.charAt(i - 1) == word2.charAt(j - 1)){dp[i][j] = dp[i - 1][j - 1];}else {dp[i][j] = Math.min(dp[i - 1][j - 1] + 1, Math.min(dp[i][j - 1] + 1, dp[i - 1][j] + 1));}}}return dp[word1.length()][word2.length()];}
}