动态规划:给定一个字符串s和一个字符串t,计算在s的子序列中t出现的个数

描述

字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置 所组成的新字符串。(例如,"ACE"是"ABCDE"的一个子序列,而"AEC"不是)
题目数据保证答案符合32位带符号整数范围。
示例 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

解析

我们拿s = “babgbag”, t = “bag”来举例分析

  1. 我们依次确认s中有多少个"b"组合、”ba“组合、”bag“组合

  2. ba组合=s中指针的位置之前已有的ba组合个数+b的个数
    第一个a: ba组合=0(前面还没有ba组合)+1(前面有一个b)=1
    第二个a: ba组合=1(前面有一个ba组合)+3(前面有三个b)=4

  3. bag组合=s中指针的位置之前已有的bag组合个数+ba的组合个数
    第一个g: bag组合=0(前面没有bag组合)+1(前面ba组合个数)=1
    第二个g: bag组合=1(前面bag组合个数)+4(前面ba组合个数)=5

代码
public static int numDistinct(String s, String t) {
        //sLength和tLength分别是两个字符串的长度
        int sLength = s.length();
        int tLength = t.length();
        int[][] dp = new int[tLength + 1][sLength + 1];
        //base case 边界条件
        for (int j = 0; j <= sLength; j++) {
            dp[0][j] = 1;
        }
        for (int i = 1; i <= tLength; i++) {
            //注意此处j的开始位置是i
            for (int j = i; j <= sLength; j++) {
                //下面是递推公式
                char chart = t.charAt(i - 1);
                char charS = s.charAt(j - 1);
                if (chart == charS) {
                    //如果字符串t的第i个字符和s的第j个字符一样, //那么有两种选择
                    int ij = dp[i - 1][j - 1];
                    int ij1 = dp[i][j - 1];
                    dp[i][j] = ij + ij1;
                } else {
                    //如果字符串t的第i个字符和s的第j个字符不一样,
                    // 我们只能用字符串s的前j-1个字符来计算他包含的数量
                    dp[i][j] = dp[i][j - 1];
                }
            }
        }
        return dp[tLength][sLength];
    }```

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值