当前位置: 首页 > news >正文

LeetCode算法日记 - Day 103: 不同的子序列

目录

1. 不同的子序列

1.1 题目解析

1.2 解法

1.3 代码实现


1. 不同的子序列

给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。

测试用例保证结果在 32 位有符号整数范围内。

示例 1:

输入:s = "rabbbit", t = "rabbit"
输出3
解释:如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。rabbbitrabbbitrabbbit

示例 2:

输入:s = "babgbag", t = "bag"
输出5
解释:如下所示, 有 5 种可以从 s 中得到 "bag" 的方案。 babgbagbabgbagbabgbagbabgbagbabgbag

提示:

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

1.1 题目解析

题目本质
子序列匹配计数问题 - 统计从长字符串中选择字符组成目标字符串的方案数。

常规解法
递归枚举所有可能的字符选择组合,对于s的每个字符,决定是否选择它来匹配t的当前位置。

// 常规递归解法
class Solution {public int numDistinct(String s, String t) {return dfs(s, t, 0, 0);}private int dfs(String s, String t, int i, int j) {// 目标字符串匹配完成if (j == t.length()) return 1;// 源字符串用完但目标字符串未完成if (i == s.length()) return 0;int res = 0;// 不选择当前字符res += dfs(s, t, i + 1, j);// 如果字符匹配,可以选择当前字符if (s.charAt(i) == t.charAt(j)) {res += dfs(s, t, i + 1, j + 1);}return res;}
}

问题分析
递归解法存在大量重复子问题,时间复杂度为O(2^n),当字符串长度达到1000时会超时。需要记忆化或动态规划优化。

思路转折
要想高效 → 必须避免重复计算 → 动态规划。观察到状态只依赖于当前处理的s和t的位置,可以用二维DP表存储中间结果,将指数时间优化为多项式时间。

1.2 解法

算法思想
使用动态规划,dp[i][j]表示s的前i个字符中组成t的前j个字符的方案数。状态转移方程:

  • 当s[i-1] == t[j-1]时:dp[i][j] = dp[i-1][j-1] + dp[i-1][j]

  • 当s[i-1] != t[j-1]时:dp[i][j] = dp[i-1][j] i)

步骤拆解

i)创建二维DP表,大小为(n+1) × (m+1)

ii)初始化边界条件:dp[i][0] = 1(任意字符串都能组成空串)

iii)双重循环填充DP表,根据字符是否匹配选择状态转移方式

iv)返回dp[n][m]作为最终答案

易错点

  • 边界初始化遗漏:忘记设置dp[i][0] = 1,导致后续计算错误

  • 数组越界:使用s[i-1]和t[j-1]时要确保i和j从1开始

1.3 代码实现

class Solution {public int numDistinct(String _s, String _t) {int n = _s.length();int m = _t.length();char[] s = _s.toCharArray();char[] t = _t.toCharArray();// 1) 创建DP表int[][] dp = new int[n + 1][m + 1];// 2) 初始化:任意长度的s都能组成空串tfor (int i = 0; i <= n; i++) {dp[i][0] = 1;}// 3) 动态规划填表for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (s[i - 1] == t[j - 1]) {// 字符匹配:可选择使用或不使用当前字符dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];} else {// 字符不匹配:只能跳过s的当前字符dp[i][j] = dp[i - 1][j];}}}// 4) 返回结果return dp[n][m];}
}

复杂度分析

  • 时间复杂度:O(n × m),需要填充n×m的DP表

  • 空间复杂度:O(n × m),DP表的存储空间

http://www.dtcms.com/a/614401.html

相关文章:

  • 怎么建立自己网站 asp个人怎么做网站排名优化
  • 20251109 树状DP总结
  • C语言编译器出现Bug | 如何解决C语言编译器常见问题
  • 做淘宝客网站php青岛网站推广企业
  • 第九篇 扫雷游戏 上(末版·精简)
  • ⚡️2025-11-15GitHub日榜Top5|热点智能推送工具
  • python做项目的网站国家标准下载网免费
  • 网站建设服务费属于基于asp网站开发 论文
  • 高斯数据库 (GaussDB) 使用指南
  • 安徽茶叶网站建设网站抽奖模块怎么做
  • 建立自己的影视网站快手免费推广软件
  • 织梦网站调整网店如何推广自己的产品
  • 构建AI智能体:九十五、YOLO视觉大模型入门指南:从零开始掌握目标检测
  • 【文档】Aerial CUDA-Accelerated RAN , Aerial cuBB 部分
  • 育儿心理学
  • 建网站公司 快云淘宝客优惠券的网站是怎么做的
  • 黑马Redis A-基础
  • 一小时速通Pytorch之神经网络相关知识(三)
  • 帝国cms小说网站模板清美未来广告设计公司
  • 从编译角度来理解匿名函数与闭包
  • 【C++】3:函数重载、内联函数和nullptr
  • 如何做旅游网站的思维导图wordpress无法访问上传的图面
  • 赣州网站推广广州市天河区发布
  • python函数(三)———学员管理系统
  • 张北县网站建设广州网站网站建设
  • 电磁场中的静态与定态两个概念
  • 南京网站建设 小程序phpcms网站模板下载
  • 昌邑网站建设公司国外有什么做网站的软件吗
  • Qt QTreeView深度解析:从原理到实战应用
  • 建设网站需要哪些经营范围免费发帖推广的平台