不同的子序列

不同的子序列

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

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

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

示例 1:

输入:s = "rabbbit", t = "rabbit"
输出:3

示例 2:

输入:s = "babgbag", t = "bag"
输出:5

解题思路:首先从s 和 t 的最后一个字符开始思考,此时有两种情况,当两字符不相等时则需要从s[0..s.length - 2]和t[0..t.length - 1]中寻找s的子序列可以转化为 t 的个数;当两字符相等时除去前面一种情况还要再加上s[0…s.length - 2]和t[0…t.length - 2]的个数,由此可以得处状态方程即可解答

class Solution {
    public int numDistinct(String s, String t) {
        char[] chs = s.toCharArray(), cht = t.toCharArray();
        
        int len1 = chs.length, len2 = cht.length;
        
        // 数组定义:dp[i][j]表示s[0..i - 1]的子序列转化为t[0..j - 1]的个数
        int dp[][] = new int[len1 + 1][len2 + 1];
        
        // 初始化 当t是空串时,s只有一个子序列可以转化为t
        for(int i = 0; i <= len1; i++) {
            dp[i][0] = 1;
        }
        
        /**
        状态方程:dp[i][j] = dp[i - 1][j] + (s[i - 1] == t[j - 1] ? dp[i - 1][j - 1] : 0)
        **/
        for(int i = 1; i <= len1; i++) {
            for(int j = 1;j <= len2; j++) {
                dp[i][j] = dp[i - 1][j];
                
                if(chs[i - 1] == cht[j - 1]) {
                    dp[i][j] += dp[i - 1][j - 1];
                }
            }
        }
        
        return dp[len1][len2];
    }
}
原文地址:https://www.cnblogs.com/katoMegumi/p/14250528.html