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

力扣115:不同的子序列

力扣115:不同的子序列

  • 题目
  • 思路
  • 代码

题目

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

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

思路

首先我们来考虑特殊情况,当s串的长度小于t串时s串肯定就没有t串了。其他情况我们就需要想一想怎么做了,如果按照暴力做法我们就遍历s串先找到t串的第一个字符然后再找第二个第三个,也就是一个一个字符的匹配,问题是题目设置的是s串的子序列而不是子串,子序列是不需要连续的所以这就导致找到了第一个字符后可能会有很多个第二个字符也就导致我们的时间复杂度会很高。那么我们是否可以换一种思想,既然是要一个一个的匹配也就是我们可以把两个字符串拆分成一个一个的字符,我们定义一个二维数组dp,设s串的下标为i,t串的下标为j。我们设dp[i][j]是s[i,…]也就是i位置到末尾的s子串种t[j,…]即j到末尾的t子串的数量,简单来说我们就是把这个问题分成了一个一个的子问题,我们利用这个二维数组来移动i和j从而得到不同的s子串中不同的t子串出现的个数。然后再找寻其中的规律推导出状态转移方程出来,所以我们是利用了动态规划的思想,把大问题分成小问题。
那么这个二维数组dp我们要如何定义呢?我们需要定义成一个(n+1)*(m+1)的,n为s串的长度m为t串的长度。为什么要+1呢因为我们需要我们从这两个子串是空串的情况开始,当s为空串t不为空串时dp[i][j] = 0因为一个空串里怎么可能有非空串,当s为非空串t为空串时dp[i][j] =1因为一个空串是任意一个非空串的子序列。所以dp[i][0] = 1( 0 <= i <= n)。在对特殊情况进行讨论后我们现在就要移动i和j来得到每一个子问题的答案了,这里需要分成两种情况。

  1. s[i-1] == t[j-1]
    当此位置的字符相同时,我们需要考虑一个问题那就是这个字符是需要匹配的吗,这是什么意思呢。我们还需要回顾一下题目说的是s串的子序列中t出现的个数,是子序列所以不是连续的所以在这两个相等的字符前面可能还有和t[j]相同的s[i],所以我们需要讨论这两种情况例如s:tbabag,t:bag。s的第一个a不是一定要和t的a进行匹配的也可以让后面那个a来和t的a进行匹配,这就是为什么要考虑是否需要匹配。如果两个字符匹配了那么此时的dp[i][j] = dp[i-1][j-1],也就是我们需要考虑t[j-1,…]作为s[i-1,…]的子序列的情况了,如果不匹配此时的dp[i][j] = dp[i-1][j],因为不匹配也就是这个i被跳过了我们就需要考虑t[j]作为s[i-1]的子序列的情况了。
  2. s[i]-1 != t[j-1]
    如果两个字符不同就说明无法匹配,dp[i][j] = dp[i+1][j]。

代码

class Solution {
public:int numDistinct(string s, string t) {int n = s.length();int m = t.length();if (n < m) {return 0;}//dp[i][j]代表t中从0到j的子串作为s中从0到i的子串的子序列的个数vector<vector<unsigned long long>> dp(n + 1, vector<unsigned long long>(m + 1));for (int i = 0; i <= n; i++) {dp[i][0] = 1;}for (int i = 1; i <= n; i++) {char si = s[i-1];for (int j = 1; j <= m; j++) {char tj = t[j-1];if (si == tj) {dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];} else {dp[i][j] = dp[i - 1][j];}}}return dp[n][m];}
};
http://www.xdnf.cn/news/1438687.html

相关文章:

  • Unity Android 文件的读写
  • Delphi 5 中操作 Word 表格时禁用鼠标交互
  • 更新远程分支 git fetch
  • 揭开PCB隐形杀手:超周期报废的技术真相
  • AI编码生产力翻倍:你必须掌握的沟通、流程、工具与安全心法
  • 一键掌握服务器健康状态与安全风险
  • 同步工具的底层依赖:AQS
  • Kubernetes 中为 ZenTao 的 Apache 服务器添加请求体大小限制
  • 如何开发一款高稳定、低延迟、功能全面的RTSP播放器?
  • 时序数据库选型指南:为何Apache IoTDB成为工业物联网首选
  • JVM分析(OOM、死锁、死循环)(JProfiler、arthas、jvm自带工具)
  • STM32 - Embedded IDE - GCC - 使用 GCC 链接脚本限制 Flash 区域
  • 【Android】从复用到重绘的控件定制化方式
  • HarmonyOS 应用开发深度解析:基于 ArkTS 的声明式 UI 与状态管理艺术
  • HarmonyOS安装以及遇到的问题
  • Jenkins-Ansible部署discuz论坛
  • 38.Ansible判断+实例
  • PINN物理信息神经网络用于求解二阶常微分方程(ODE)的边值问题,Matlab实现
  • 力扣hot100:缺失的第一个正数(哈希思想)(41)
  • Qwen3-30B-A3B 模型解析
  • 【C++】迭代器详解与失效机制
  • # Shell 文本处理三剑客:awk、sed 与常用小工具详解
  • 【前端面试题✨】Vue篇(一)
  • Linux网络序列化与反序列化(6)
  • Linux文本处理——awk
  • 飞牛OS Nas,SSH安装宝塔后,smb文件不能共享问题
  • STM32——串口
  • 2025年- H109-Lc1493. 删掉一个元素以后全为 1 的最长子数组(双指针)--Java版
  • 别再误会了!Redis 6.0 的多线程,和你想象的完全不一样
  • 从入门到实战:Linux sed命令全攻略,文本处理效率翻倍