算法day39-动态规划(12)
目录
- 不同的子序列
- 两个字符串的删除操作
- 编辑距离
一、不同的子序列
https://leetcode.cn/problems/distinct-subsequences/?envType=problem-list-v2&envId=8At1GmaZ

class Solution { public int numDistinct(String s, String t) { //d[i][j]:以i-1结尾的s子序列中有以j-1结尾的t的个数 int[][] dp = new int[s.length()+1][t.length()+1]; for(int i=0; i<s.length()+1; i++){ dp[i][0] = 1; } for(int i=1; i<s.length()+1; i++){ for(int j=1; j<t.length()+1; j++){ if(s.charAt(i-1) == t.charAt(j-1)){ //使用s.charAt(i-1)和模拟删除这个元素的操作 dp[i][j] = dp[i-1][j-1] + dp[i-1][j]; }else{ dp[i][j] = dp[i-1][j]; } } } return dp[s.length()][t.length()]; } }
二、两个字符串的删除操作
https://leetcode.cn/problems/delete-operation-for-two-strings/?envType=problem-list-v2&envId=8At1GmaZ

class Solution { public int minDistance(String word1, String word2) { //dp[i][j]:以i-1结尾的word1和以j-1结尾的word2变得结尾所需的最小步数 int[][] dp = new int[word1.length()+1][word2.length()+1]; 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; } 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, dp[i][j-1]+1); } } } return dp[word1.length()][word2.length()]; } }
三、编辑距离
https://leetcode.cn/problems/edit-distance/description/?envType=problem-list-v2&envId=8At1GmaZ


1. 定义状态
定义一个二维数组 dp,其中 dp[i][j] 表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符所需的最小操作数。
2. 初始化
-
dp[0][j] = j:表示将空字符串转换为word2的前j个字符需要插入j个字符。 -
dp[i][0] = i:表示将word1的前i个字符转换为空字符串需要删除i个字符。
3. 状态转移
对于 dp[i][j]:
-
如果
word1.charAt(i-1) == word2.charAt(j-1),说明word1[i-1]和word2[j-1]相同,不需要进行任何操作,此时dp[i][j] = dp[i-1][j-1]。 -
如果
word1.charAt(i-1) != word2.charAt(j-1),我们需要选择以下三个操作中的最小代价:-
删除字符:
dp[i-1][j] + 1,即从word1删除一个字符,保持word2不变。 -
插入字符:
dp[i][j-1] + 1,即向word1中插入一个字符,使其与word2匹配。 -
替换字符:
dp[i-1][j-1] + 1,即将word1[i-1]替换为word2[j-1]。
-
4. 返回结果
最后,dp[word1.length()][word2.length()] 即为将整个 word1 转换为 word2 的最小编辑距离。
时间复杂度
-
时间复杂度:
O(m * n),其中m和n分别是word1和word2的长度。我们需要遍历二维数组dp,每个元素的填充操作是常数时间。 -
空间复杂度:
O(m * n),需要O(m * n)的空间来存储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()+1; i++){ dp[i][0] = i; } for(int j=0; j<word2.length()+1; j++){ dp[0][j] = j; } 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(Math.min(dp[i-1][j]+1, dp[i][j-1]+1), dp[i-1][j-1]+1); } } } return dp[word1.length()][word2.length()]; } }
浙公网安备 33010602011771号