day55【动态规划子序列】392.判断子序列 115.不同的子序列

文章目录

  • 392.判断子序列
  • 115.不同的子序列

392.判断子序列

  • 题目链接:力扣链接

  • 讲解链接:代码随想录讲解链接

  • 题意:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

    字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

    进阶:
    如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

      示例 1:
      输入:s = "abc", t = "ahbgdc"
      输出:true
      
      示例 2:
      输入:s = "axc", t = "ahbgdc"
      输出:false
    
  • 思路看代码注释

class Solution {
    public boolean isSubsequence(String s, String t) {
        char[] chars = s.toCharArray();
        char[] chart = t.toCharArray();

        //dp[][]表示以i-1为结尾的s和以j-1为结尾的t,相同子序列的长度为dp[i][j]
        int[][] dp = new int[chars.length+1][chart.length+1];

        //初始化:dp表示以i-1和j-1为结尾,那么dp[0][j]和dp[i][0]是无意义的,初始化为0即可。其他是由前面推导的,也赋值为0就行。

        for(int i = 1; i <= chars.length; i++) {
            for(int j = 1; j <= chart.length; j++) {
                //dp代表以i-1和j-1结尾的数组,所以是chars[i-1]和chars[j-1]比较
                if(chars[i-1] == chart[j-1]) {
                    dp[i][j] = dp[i-1][j-1] + 1;
                } else { //判断s是否为t的子序列,那么删除t里的元素即可;
                //如果chars[i-1]和chart[j-1]此时不相等,那么就把此时的chart[j-1]这个元素删除即可,那么dp[i][j]就是看chars[i-1]和chart[i-2]的比较了,也即dp[i][j-1];
                    dp[i][j] = dp[i][j-1];
                }
            }
        }

        //如果以s和t字符串的长度为结尾的相同子序列的长度和s的长度是相同的话,那说明t中包含s的子序列
        if(dp[chars.length][chart.length] == chars.length) {
            return true;
        } else {
            return false;
        }
    }
}

115.不同的子序列

  • 题目链接:力扣链接

  • 讲解链接:代码随想录讲解

  • 题意:给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 10e9 + 7 取模。

      示例 1:
      输入:s = "rabbbit", t = "rabbit"
      输出:3
      解释:
      如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
      rabbbit
      rabbbit
      rabbbit
      
      示例 2:
      输入:s = "babgbag", t = "bag"
      输出:5
      解释:
      如下所示, 有 5 种可以从 s 中得到 "bag" 的方案。 
      babgbag
      babgbag
      babgbag
      babgbag
      babgbag
    
  • 思路 :看代码(自己还有点迷糊)

class Solution {
    public int numDistinct(String s, String t) {
        char[] charS = s.toCharArray();
        char[] charT = t.toCharArray();

        //代表以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]
        int[][] dp = new int[charS.length+1][charT.length+1];

        //初始化
        //dp[i][0]代表以i-1为结尾的子序列中出现以空字符串为结尾的个数,只有把s中的元素都删除了,才会出现一个空字符串,即dp[i][0]为1;
        //dp[0][j]代表以空字符串为结尾的子序列中出现以j结尾的的个数,无论如何,空字符串都变不成t,即dp[0][j]=0;
        for(int i = 0; i <= charS.length; i++) {
            dp[i][0] = 1;
        }

        for(int i = 1; i <= charS.length; i++) {
            for(int j = 1; j <= charT.length; j++){
                if(charS[i-1] == charT[j-1]) {
                    //把当前两个元素相等的个数 + s中之前的重复元素的个数
                    dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                } else {
                    //两个元素不相等时,看s中是否有t,那就删除此时的s中的元素,看s中前一个元素和当前j的元素的个数
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        return dp[charS.length][charT.length]; 
    }
}

你可能感兴趣的:(动态规划,算法)