前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >☆打卡算法☆LeetCode 115、 不同的子序列 算法解析

☆打卡算法☆LeetCode 115、 不同的子序列 算法解析

作者头像
恬静的小魔龙
发布2022-08-07 10:28:57
2110
发布2022-08-07 10:28:57
举报
文章被收录于专栏:Unity3D
大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。

一、题目

1、算法题目

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

题目链接:

来源:力扣(LeetCode)

链接: 115. 不同的子序列

2、题目描述

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

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

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

代码语言:javascript
复制
示例 1:
输入:s = "rabbbit", t = "rabbit"
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
rabbbit
rabbbit
rabbbit
代码语言:javascript
复制
示例 2:
输入:s = "babgbag", t = "bag"
输出:5
解释:
如下所示, 有 5 种可以从 s 中得到 "bag" 的方案。 
babgbag
babgbag
babgbag
babgbag
babgbag

二、解题

1、思路分析

这道题可以考虑使用动态规划的方法阶梯,假设字符串s和t的长度为m和n,要算s的子序列在t中出现的个数,那么s的长度一定大于或等于t的长度,也就是只有当m≥n的时候,个数才大于0,如果m≤n,就直接返回0。

创建二维数组dp,其中dp[i][j]表示前 t[i] 个字符可以由 s[j] 字符串组成的个数。

所以动态规划方程: 当 s[j] == t[i] , dp[i][j] = dp[i-1][j-1] + dp[i][j-1]

当s[j] != t[i] , dp[i][j] = dp[i][j-1]

通过动态方程,最终计算得到dp[0][0]即为在s的子序列中t出现的个数。

2、代码实现

代码参考:

代码语言:javascript
复制
class Solution {
    public int numDistinct(String s, String t) {
        int m = s.length(), n = t.length();
        if (m < n) {
            return 0;
        }
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i <= m; i++) {
            dp[i][n] = 1;
        }
        for (int i = m - 1; i >= 0; i--) {
            char sChar = s.charAt(i);
            for (int j = n - 1; j >= 0; j--) {
                char tChar = t.charAt(j);
                if (sChar == tChar) {
                    dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j];
                } else {
                    dp[i][j] = dp[i + 1][j];
                }
            }
        }
        return dp[0][0];
    }
}
image.png
image.png

3、时间复杂度

时间复杂度 : O(mn)

其中m和n分别是字符串s和t的长度,对于二维数组来说,需要对dp中每个元素进行计算。

空间复杂度: O(mn)

其中m和n分别是字符串s和t的长度。

三、总结

题解中的关键:

s[i] == t[j]的时候, s[i] 可以选择自己是否跟 t[j]匹配

  • 如果匹配,那么 dp[i][j] 其中一部分数量就是 dp[i+1][j+1]
  • 如果选择不匹配(这样可以让前面的字符跟t[j]匹配,毕竟t 短的,s 长) dp[i][j] 另外一部分就是 dp[i+1][j]

所以才会有:

代码语言:javascript
复制
dp[i][j] = dp[i+1][j+1] + dp[i+1][j]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目
    • 1、算法题目
      • 2、题目描述
      • 二、解题
        • 1、思路分析
          • 2、代码实现
            • 3、时间复杂度
            • 三、总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档