题目1: 两个字符串的删除操作
- 题目链接:583. 两个字符串的删除操作
1- 思路
动规五部曲
- 1. 确定 dp 数组含义
dp[i][j]
代表以i-1
的word1
和 以j-1
为结尾的word2
,让两者相同的最少操作次数为dp[i][j]
- 2. 确定递推公式
- 比较两个单词的字符 即
word1[i-1] == word2[j-1]
- ① 若两个单词相等
if(word1[i-1] == word2[j-1])
此时不考虑删除操作dp[i][j] = dp[i-1][j-1]
- ② 若不相等
dp[i][j]
来源于- 删除
word1
的最后一个单词 +1 删除操作 - 删除
word2
的最后一个单词 +1 删除操作 - 两个单词最后一个元素都删除 +2 删除操作
- 删除
dp[i][j] = Math.min(dp[i-1][j]+1,Math.min(dp[i][j-1]+1,dp[i-1][j-1]+2);
- 比较两个单词的字符 即
- 3. dp 数组初始化
- 第一行、第一列元素初始化
- 其中第一行代表,
dp[0][j]
,长度为j
的word2
变为 长度为0
的word1
需要的操作就是word2
的长度 - 其中第一列代表,
dp[i][0]
,长度为i
的word1
变为 长度为0
的word2
需要的操作就是word1
的长度
- 4. 遍历顺序
i
从1
遍历到i<word1.length+1
j
从1
遍历到j<word2.length+1
- 5. 推导dp 数组
2- 题解
⭐ 两个字符串的删除操作——题解思路
class Solution {
public int minDistance(String word1, String word2) {
// 1. 定义 dp数组
int[][] dp = new int[word1.length()+1][word2.length()+1];
// 2.递推公式
// if(word1[i]==word2[j])
// 相等则 dp[i][j] = dp[i-1][j-1]
// 不相等 dp[i][j] = Math.min(dp[i-1][j]+1,Math.min(dp[i][j-1]+1,dp[i-1][j-1]+2));
// 3. 初始化
// 1列
for(int i = 0 ; i < word1.length()+1;i++){
dp[i][0] = i;
}
// 1行
for(int j = 0; j < word2.length()+1;j++){
dp[0][j] = j;
}
// 4. 遍历顺序
for(int i = 1 ; i < word1.length()+1;i++){
for(int j = 1 ; j < word2.length()+1;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()];
}
}
题目2: 编辑距离
- 题目链接:72. 编辑距离
1- 思路
动规五部曲
- 1. 确定 dp 数组含义
dp[i][j]
代表以i-1
结尾的word1
和以j-1
为结尾的word2
,使两个单词相等的最少操作次数
- 2. 确定递推公式
- ① 如果当前最后一位的元素相同
word1[i] = word2[j]
,此时dp[i][j] = dp[i-1][j-1]
- ② 如果不相同
- 删
word1
、删word2
/ 增操作dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])
- 换的目的是达到相同,相同情况下
dp[i][j] = dp[i-1][j-1]
,则替换操作的代价是在相同操作上做一次替换,则dp[i][j] = dp[i-1][j-1] + 1
。
- 删
- ① 如果当前最后一位的元素相同
- 3. dp 数组初始化
- 第一行,代表 word1 为 0 变为 word2 的操作数 即 为 j
- 第一列,代表 word2 为 0 变为 wrod1 的操作数 即 为 i
- 4. 遍历顺序
- i 从 1 遍历到 word1.length
- j 从 1 遍历到 word2.length
- 5. 推导dp 数组
2- 题解
⭐编辑距离——题解思路
class Solution {
public int minDistance(String word1, String word2) {
// 1. 定义 dp
int[][] dp = new int[word1.length()+1][word2.length()+1];
// 2. 递推公式
// 相等 word1.charAt(i) == word2.charAt(j)
// dp[i][j] = dp[i-1][j-1]
// 不等 dp[i][j] = Math.min(dp[i-1][j]+1,Math.min(dp[i][j-1]+1,dp[i-1][j-1]+1));
// 3. 初始化
for(int i = 0 ; i < word1.length()+1;i++){
dp[i][0] = i;
}
for(int j = 0 ; j < word2.length()+1;j++){
dp[0][j] = j;
}
// 4. 遍历顺序
for(int i = 1 ; i < word1.length()+1;i++){
for(int j = 1 ; j < word2.length()+1;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]+1));
}
}
}
return dp[word1.length()][word2.length()];
}
}