583. 两个字符串的删除操作
思路: 和1143.最长公共子序列这道题思路相同,只不过需要对return的数据做一些操作。
class Solution {public int minDistance(String word1, String word2) {int[][] dp=new int[word1.length()+1][word2.length()+1];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]+1;}else{dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);}}}return word1.length()+word2.length()-2*dp[word1.length()][word2.length()];}
}
时间复杂度:O(nm)
空间复杂度:O(nm)
72. 编辑距离
- 确定dp数组(dp table)以及下标的含义
dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。 - 确定递推公式
在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:
if (word1[i - 1] == word2[j - 1])不操作
if (word1[i - 1] != word2[j - 1])增 //dp[i][j-1]+1 或 dp[i-1][j]+1删 //dp[i][j-1]+1 或 dp[i-1][j]+1换 //dp[i-1][j-1]+1
-
dp数组如何初始化
再回顾一下dp[i][j]的定义:
dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]。
那么dp[i][0] 和 dp[0][j] 表示什么呢?
dp[i][0] :以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。
那么dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i;
同理dp[0][j] = j; -
确定遍历顺序
从如下四个递推公式:
dp[i][j] = dp[i - 1][j - 1]
dp[i][j] = dp[i - 1][j - 1] + 1
dp[i][j] = dp[i][j - 1] + 1
dp[i][j] = dp[i - 1][j] + 1
可以看出dp[i][j]是依赖左方,上方和左上方元素的。因此两层循环均采用正向遍历。
- 打印dp数组。
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 i=0;i<=word2.length();i++) dp[0][i]=i;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-1][j]+1,dp[i][j-1]+1));}} }return dp[word1.length()][word2.length()];}
}
时间复杂度:O(nm)
空间复杂度:O(nm)