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

不同的子序列-java

  • 题目描述(力扣题库115):

    • 给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。

      示例 1:

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

    • 动态规划 : 

    • 当解决动态规划问题时,通常需要定义一个状态数组来存储中间结果。在这个问题中,我们使用二维数组 `dp` 来表示状态。`dp[i][j]` 表示在字符串 `s` 的子串 `s[i:]` 中出现字符串 `t` 的子串 `t[j:]` 的次数。

      首先,我们从字符串的末尾开始向前遍历。这是因为我们需要依赖后面的状态来计算当前状态。我们将 `dp[i][t.length()]` 初始化为 1,因为对于任何非空字符串 `s`,其末尾与空字符串匹配的次数都是 1。

      然后,我们从 `s` 和 `t` 的末尾开始逐个字符进行比较。如果 `s[i]` 与 `t[j]` 相等,则意味着我们有两种选择:

      1. 保留 `s[i]`,并且尝试匹配 `s[i + 1:]` 和 `t[j + 1:]`,所以此时的状态转移方程为 `dp[i][j] = dp[i + 1][j + 1]`。
      2. 匹配 `s[i]` 和 `t[j]`,然后尝试匹配 `s[i + 1:]` 和 `t[j:]`,所以此时的状态转移方程为 `dp[i][j] += dp[i + 1][j]`。

      如果 `s[i]` 与 `t[j]` 不相等,则意味着我们不能匹配当前字符,只能选择保留 `s[i]` 并尝试匹配 `s[i + 1:]` 和 `t[j:]`,所以状态转移方程为 `dp[i][j] = dp[i + 1][j]`。

      通过不断地更新状态数组 `dp`,最终我们就可以得到整个字符串 `s` 和 `t` 的子序列匹配次数,即 `dp[0][0]`。

      这种动态规划的解法利用了子问题的重叠性质,避免了重复计算,从而实现了高效的解决方案。

  • 解题步骤: 

  1. 初始化状态数组

    • 创建一个二维数组 dp,其大小为 (s.length() + 1) × (t.length() + 1)
    • 初始化 dp[i][t.length()] = 1,表示任何非空字符串 s 的末尾与空字符串匹配的次数都是 1。
  2. 逆向遍历字符串

    • 从 s 和 t 的末尾开始向前遍历字符。
    • 遍历的范围是 i = s.length() - 1 到 0,以及 j = t.length() - 1 到 0
  3. 状态转移

    • 对于当前位置 (i, j),判断 s[i] 和 t[j] 是否相等:
      • 如果相等,则有两种选择:
        • 保留 s[i],并尝试匹配 s[i + 1:] 和 t[j + 1:],更新状态:dp[i][j] = dp[i + 1][j + 1]
        • 匹配 s[i] 和 t[j],并尝试匹配 s[i + 1:] 和 t[j:],更新状态:dp[i][j] += dp[i + 1][j]
      • 如果不相等,则只能保留 s[i],并尝试匹配 s[i + 1:] 和 t[j:],更新状态:dp[i][j] = dp[i + 1][j]
  4. 返回结果

    最终的结果存储在 dp[0][0] 中,表示整个字符串 s 和 t 的子序列匹配次数。

通过以上步骤,可以得到字符串 s 和 t 的子序列匹配次数。这个算法的时间复杂度为 O(mn),其中 m 是字符串 s 的长度,n 是字符串 t 的长度。

  • 以下是代码实现: 
    • class Solution {public int numDistinct(String s, String t){if(s.length() < t.length()) return 0;int[][] dp = new int[s.length() + 1][t.length() + 1];for (int i = 0; i <= s.length(); i++) {dp[i][t.length()] = 1;}for (int i = s.length() - 1; i >= 0; i--) {for (int j = t.length() - 1; j >= 0; j--) {if(s.charAt(i) == t.charAt(j))dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j];elsedp[i][j] = dp[i + 1][j];}}return dp[0][0];}
      }

  

  •                       以上是本篇文章的全部内容, 感谢观看

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • UE4_动画基础_角色的缩放
  • conda创建虚拟环境太慢,Collecting package metadata (current_repodata.json): failed
  • SQLite数据库的性能问题并不是单纯地由数据量的大小决定的,而是受到多种因素的综合影响。以下是一些可能导致SQLite性能问题的因素
  • MongoDB聚合运算符:$map
  • AJAX —— 学习(一)
  • Leetcode56_合并区间
  • 21. 面试指导-高频面试题详解
  • 一次部署,多处运行:Docker容器化开发
  • Java 处理Mysql获取树形的数据
  • SpringBoot多级多模块聚合项目下maven打包报‘packaging‘ with value ‘jar‘ is invalid.
  • 图书馆自助借书机怎么借书
  • Bash相关
  • Mysql安装(命令方式安装)
  • 基于深度学习的电动自行车头盔佩戴检测系统
  • 06-User Login
  • Babel配置的不完全指南
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • ES6语法详解(一)
  • JavaScript设计模式之工厂模式
  • Java比较器对数组,集合排序
  • java小心机(3)| 浅析finalize()
  • React系列之 Redux 架构模式
  • use Google search engine
  • 对超线程几个不同角度的解释
  • ------- 计算机网络基础
  • 离散点最小(凸)包围边界查找
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 删除表内多余的重复数据
  • 使用 @font-face
  • 跳前端坑前,先看看这个!!
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 在weex里面使用chart图表
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • hi-nginx-1.3.4编译安装
  • puppet连载22:define用法
  • ​TypeScript都不会用,也敢说会前端?
  • # 计算机视觉入门
  • #git 撤消对文件的更改
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (09)Hive——CTE 公共表达式
  • (1)bark-ml
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (七)Java对象在Hibernate持久化层的状态
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (转)ORM
  • (转)平衡树
  • .gitignore文件设置了忽略但不生效
  • .mysql secret在哪_MYSQL基本操作(上)
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .NET委托:一个关于C#的睡前故事
  • .net知识和学习方法系列(二十一)CLR-枚举