代码随想录 (programmercarl.com)
本题和LC115.不同的子序列?相比,其实就是两个字符串都可以删除了,情况虽说复杂一些,但整体思路是不变的。
1.dp数组及下标含义
dp[i][j]:表示使以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t相同的最小操作步数为dp[i][j]。
2.递推公式
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()];
}
}
注意: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()];
}
}