Day36 | 392判断子序列&115不同的子序列&583两个字符串的删除操作&72编辑距离

56 阅读2分钟

判断子序列 LeetCode 392

题目链接:[LeetCode 392 - 简单]

思路

本来打算使用boolean数组作为dp数组,但是校验比较难。 还是使用int数组更为保险且代码容易写。

动态规划:

class Solution {
    public boolean isSubsequence(String s, String t) {
        int len1=s.length();
        int len2=t.length();
        int[][] dp = new int[len1+1][len2+1];

        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(s.charAt(i-1)==t.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=dp[i][j-1];
                }
            }
        }
        if(dp[len1][len2]==len1){
            return true;
        }else{
            return false;
        }
    }
}

不同的子序列 LeetCode 155

题目链接:[LeetCode 155 - 困难]

思路

动态规划:

class Solution {
    public int numDistinct(String s, String t) {
        int len1 = s.length();
        int len2 = t.length();
        int[][] dp = new int[len1+1][len2+1];
        for(int i=0;i<=len1;i++){
            dp[i][0]=1;
        }
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(s.charAt(i-1)==t.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
                }else{
                    dp[i][j]=dp[i-1][j];
                }
            }
        }
        return dp[len1][len2];
    }
}

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

题目链接:[LeetCode 583 - 中等]

思路

大部分的内容能够想到

但是递推公式:dp[i][j]=dp[i-1][j-1]+1和dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);

动态规划:

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

编辑距离 LeetCode 72

题目链接:[LeetCode 72 - 中等]

思路

动态规划五部曲:

①确认dp数组和下标:

下标为i-1的word1和下标为j-1的word2之间的距离

②递推公式:

word1[i - 1] == word2[j - 1]:dp[i][j]=dp[i-1][j-1];

word1[i - 1] != word2[j - 1]:dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;

③初始化数组:

dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i; dp[0][j]同理

④遍历顺序: 一定是从左到右从上到下去遍历

动态规划:

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(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                }
            }
        }
        return dp[word1.length()][word2.length()];
    }
}