代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列

代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列

  • 392.判断子序列
    • 解法一:动态规划
    • 解法二:双指针
  • 115.不同的子序列
    • 解法一:动态规划


392.判断子序列

教程视频:https://www.bilibili.com/video/BV1tv4y1B7ym/
代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列_第1张图片
代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列_第2张图片

解法一:动态规划

思路:
1、dp[i][j]定义:以i-1结尾的s和以j-1结尾的t的相同子序列长度。
2、递推公式:

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];//只要减少t的索引即可
}

3、dp数组初始化:为简化初始化流程,将dp[i][0]和dp[0][j]都初始化为0,其余下标会被覆盖
4、遍历顺序:当前状态由前一状态推导而来,外层for正序遍历s,内层for正序遍历t
5、打印验证。

class Solution {
    public boolean isSubsequence(String s, String t) {
        if(s==null||s.length()==0)return true;
        if(t.length()<s.length())return false;
        int[][] dp = new int[s.length()+1][t.length()+1];

        for(int i=1;i<=s.length();i++){
            for(int j=1;j<=t.length();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[i][j]==s.length())return true;
            }
        }
        return false;
    }
}

解法二:双指针

class Solution {
    public boolean isSubsequence(String s, String t) {
        int n = s.length(), m = t.length();
        int i = 0, j = 0;
        while (i < n && j < m) {
            if (s.charAt(i) == t.charAt(j)) {
                i++;
            }
            j++;
        }
        return i == n;
    }
}

115.不同的子序列

教程视频:https://www.bilibili.com/video/BV1fG4y1m75Q
代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列_第3张图片
代码随想录算法训练营day55 | 392.判断子序列,115.不同的子序列_第4张图片

解法一:动态规划

思路:
1、dp[i][j]定义:以i-1为结尾的t 在以 j-1为结尾的s 中出现的个数
2、递推公式:

if(t.charAt(i-1)==s.charAt(j-1)){
    dp[i][j]=dp[i-1][j-1]+dp[i][j-1];
}else{
    dp[i][j]=dp[i][j-1];
}

3、dp数组初始化:当t为空字符串时,s删除全部元素可获得t,因此dp[0][j]初始化为1,其余下标初始化为0.
4、遍历顺序:外层for正向遍历t,内层for正向遍历s
5、打印验证。

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

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