子序列的个数

给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。

字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。

(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)

题目数据保证答案符合 32 位带符号整数范围。

115.不同的子序列示例

提示:

0 <= s.length, t.length <= 1000 s 和 t 由英文字母组成

思路

  1. 确定dp数组(dp table)以及下标的含义

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。

 

 

 

 

  1. 确定递推公式

这一类问题,基本是要分析两种情况

  • s[i - 1] 与 t[j - 1]相等
  • s[i - 1] 与 t[j - 1] 不相等

当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。

一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。

一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。

 

 

 

 

  1. dp数组如何初始化
  1. 确定遍历顺序
  1. 举例推导dp数组

 

 

    public int numDistinct(String s, String t) {
        //dp[i][j] 0...i,0...j 的个数
        //dp[i-1][j] no i. 0...i-1,0...j
        //dp[i-1][j-1] yes i,0...i-1,0..j-1 condition s[i]=t[j]
        // dp[i][0]=1 ,dp[0][j]=0

        char[] S=s.toCharArray();
        char[] T=t.toCharArray();

        int n=s.length();
        int m=t.length();
        
        int[][] dp=new int[n+1][m+1];
        for(int i=0;i<=n;i++){
            dp[i][0]=1;
        }

        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                dp[i][j]=dp[i-1][j];
               if(S[i-1]==T[j-1]){
                    dp[i][j]+=dp[i-1][j-1];
                }
            }
        }
        return dp[n][m];

    }

  

  

posted @ 2021-09-24 16:22  sherry001  阅读(196)  评论(0)    收藏  举报