不同的子序列

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

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

示例 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
    ^^^

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

在这里插入图片描述

解答:

class Solution {
       /**
        * dg[i][j] 为结果,这里i的取值范围为t的长度;j的取值范围为s的长度

        * 如果t[i]!=s[j],最后一个字符不一致,则dg[i][j]=dg[i][j-1]

        * 如果t[i]==s[j],最后一个字符一致,则dg[i][j]=dg[i-1][j-1]+dg[i][j-1]
        * 这里的理解为:dg[i-1][j-1]最后一个字符一致,加上最后一个字符就是正确结果
        * dg[i][j-1]表示:前方已经有的组合已经正确,即使不需要最后一个字符,也是正确结果
        */
       public int numDistinct(String s, String t) {
             if (s.length() == 0 || t.length() == 0) {
                    return 0;
             }
             char[] sArr = s.toCharArray();
             char[] tArr = t.toCharArray();
             long[][] dg = new long[t.length()][s.length()];
             // 对第一行进行初始化
             int temp = 0;
             for (int j = 0; j < sArr.length; j++) {
                    if (sArr[j] == tArr[0]) {
                           temp++;
                           dg[0][j] = temp;
                    } else {
                           dg[0][j] = temp;
                    }
             }
             for (int i = 1; i < tArr.length; i++)
                    for (int j = 1; j < sArr.length; j++) {
                           if (tArr[i] == sArr[j]) {
                                 dg[i][j] = dg[i - 1][j - 1] + dg[i][j - 1];
                           } else {
                                 dg[i][j] = dg[i][j - 1];
                           }
                    }
             return (int) dg[tArr.length - 1][sArr.length - 1];
       }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值