代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇

代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇

  • 583. 两个字符串的删除操作
    • 解法一:动态规划
    • 解法二:计算最长公共子序列,然后用数组长度减掉子序列长度
  • 72. 编辑距离
    • 解法一:动态规划
  • 编辑距离总结篇


583. 两个字符串的删除操作

教程视频:https://www.bilibili.com/video/BV1we4y157wB
代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇_第1张图片

解法一:动态规划

思路:
1、dp[i][j]定义:以索引i-1结尾的word1和以j-1结尾的word2相同所需要的最小步数
2、递推公式:

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], dp[i][j-1])+1;
 }

3、初始化dp:索引包含0表示空串,dp[i][0]=i; dp[0][j]=j;
4、 遍历顺序:两层for均正向遍历
5、打印验证

class Solution {
    public int minDistance(String word1, String word2) {
        // 1. dp[i][j]定义:以索引i-1结尾的word1和以j-1结尾的word2相同所需要的最小步数
        int[][] dp = new int[word1.length()+1][word2.length()+1];

        // 3. 初始化dp:索引包含0表示空串,dp[i][0]=i; dp[0][j]=j;
        for(int i=1;i<=word1.length();i++){
            dp[i][0]=i;
        }
        for(int j=1;j<=word2.length();j++){
            dp[0][j]=j;
        }

        // 4. 遍历顺序:两层for均正向遍历
        for(int i=1;i<=word1.length();i++){
            for(int j=1;j<=word2.length();j++){
                // 2. 递推公式:
                if(word1.charAt(i-1)==word2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1];
                }else{
                	// 这里简化了dp[i-1][j-1]+2
                    dp[i][j]=Math.min(dp[i-1][j], dp[i][j-1])+1;
                }
            }
        }
        // 5. 打印验证
        return dp[word1.length()][word2.length()];    
    }
}

解法二:计算最长公共子序列,然后用数组长度减掉子序列长度

结果为word1.length()+word2.length()-2*childLength

最长公共子序列代码见:https://editor.csdn.net/md/?articleId=130897102

72. 编辑距离

教程视频:https://www.bilibili.com/video/BV1qv4y1q78f
代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇_第2张图片
代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇_第3张图片

解法一:动态规划

思路:
1、dp[i][j]定义:以索引i-1结尾的word1和以j-1结尾的word2相同所需要的最少操作次数
2、递推公式:

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));
 }

3、初始化dp:索引包含0表示空串,dp[i][0]=i; dp[0][j]=j;
4、 遍历顺序:两层for均正向遍历
5、打印验证

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++){
            dp[i][0]=i;
        }
        for(int j=1;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-1][j-1]+1
                	// 增加和删除互为逆向操作,逻辑一样,金考虑删除即可Math.min(dp[i-1][j]+1, dp[i][j-1]+1)
                    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()];
    }
}

编辑距离总结篇

教程:动态规划之编辑距离总结篇
结合我的笔记:
代码随想录算法训练营day52 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组
代码随想录算法训练营day53 | 1143.最长公共子序列,1035.不相交的线,53. 最大子序和 动态规划
代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列

  1. 判断子序列只需要计算删除的情况,不用考虑增加和替换的情况,递推公式为:
if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = dp[i][j - 1];

  1. 不同的子序列虽然也只有删除操作,不用考虑替换增加之类的,但可以重复匹配,递推公式变为:
if (s[i - 1] == t[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
    dp[i][j] = dp[i - 1][j];
}
  1. 两个字符串的删除操作。
    当word1[i - 1] 与 word2[j - 1]相同的时候,dp[i][j] = dp[i - 1][j - 1];
    当word1[i - 1] 与 word2[j - 1]不相同的时候,dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
if (word1[i - 1] == word2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1];
} else {
    dp[i][j] = Math.min(dp[i - 1][j - 1] + 2, Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1));
}

  1. 编辑距离
    代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇_第4张图片
    word2添加一个元素,相当于word1删除一个元素,由此可见增加和删除互为逆向操作,word2添加一个元素d,也就是相当于word1删除一个元素d,操作数是一样!所以递推公式为:
if (word1[i - 1] == word2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1];
}else {
    dp[i][j] = Math.min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
}


你可能感兴趣的:(代码随想录训练营,算法,leetcode,动态规划)