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

【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列

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

示例 1:
输入:s = “rabbbit”, t = “rabbit”
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 “rabbit” 的方案。
在这里插入图片描述

示例 2:
输入:s = “babgbag”, t = “bag”
输出:5
解释:
如下所示, 有 5 种可以从 s 中得到 “bag” 的方案。
在这里插入图片描述

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

动态规划

class Solution {
public:int numDistinct(string s, string t) {int MOD = 1e9 + 7;int m = s.size(), n = t.size();if(n > m){return 0;}vector<vector<int>> f(m+1, vector<int>(n+1));for(int i = 0; i <= m; i++){f[i][0] = 1;}for(int i = 1; i <= m; i++){for(int j = 1; j <= min(i, n) ; j++){if(s[i-1] == t[j-1]){f[i][j] = (f[i-1][j-1] + f[i-1][j]) % MOD;}else{f[i][j] = f[i-1][j] % MOD;}}}return f[m][n];}
};

时间复杂度:O(mn),其中 m 和 n 分别是字符串 s 和 t 的长度。二维数组 dp 有 m+1 行和 n+1 列,需要对 dp 中的每个元素进行计算。

空间复杂度:O(mn),其中 m 和 n 分别是字符串 s 和 t 的长度。创建了 m+1 行 n+1 列的二维数组 dp。

这个题运用了动态规划的思想,我们首先定义一个二维动态数组f[i][j],设 f[i][j] 表示字符串 s 的前 i 个字符中,子序列中 t 的前 j 个字符出现的次数。

如果 s[i - 1] == t[j - 1],那么 f[i][j] 既可以选择使用 s[i - 1] 来匹配 t[j - 1],也可以不使用 s[i - 1]。此时状态转移方程为:

f[i][j] = (f[i-1][j-1] + f[i-1][j]) % MOD;

如果 s[i - 1] != t[j - 1],则无法匹配 t[j - 1],因此只能继承之前的状态:

f[i][j] = f[i - 1][j]

最后返回f[m][n]。


优化:滚动数组

class Solution {
public:int numDistinct(string s, string t) {int MOD = 1e9 + 7;int m = s.size(), n = t.size();if(n > m){return 0;}vector<int> f(n+1);f[0] = 1;for(int i = 1; i <= m; i++){for(int j = min(i, n); j >= 1 ; j--){if(s[i-1] == t[j-1]){f[j] = (f[j-1] + f[j]) % MOD;}}}return f[n];}
};

我们可以观察到f[i][j] = (f[i-1][j-1] + f[i-1][j]) % MOD;中,f[I][j]上一行的前一个字符转换而来,还有由同一行的前一个字符转换而来。所以我们可以省去行的空间,只定义一个包含列的一维数组f[n],我们在循环中让j倒序,我们就有f[j-1]等同于f[i-1][j-1],f[j]等同于f[i-1][j]。并且在f[i][j] = f[i-1][j] % MOD;中,f[i-1][j]会转换成f[j] = f[j],所以我们不需要列出这种情况。

http://www.lryc.cn/news/454358.html

相关文章:

  • 深入理解 JavaScript 中的 void`运算符和 yield*表达式
  • 第四节——从深层剖析指针(让你不再害怕指针)
  • openpnp - 吸嘴校正失败的opencv参数分析
  • 【Python】Marmir 使用指南:Python 驱动的电子表格生成器
  • 深入理解 JavaScript 事件循环机制:单线程中的异步处理核心
  • Stream流的终结方法(二)——collect
  • 【C语言系统编程】【第一部分:操作系统知识】1.1.操作系统原理
  • 基于Java+VUE+echarts大数据智能道路交通信息统计分析管理系统
  • leetcode-42. 接雨水 单调栈
  • ThinkPHP和PHP的区别
  • clientWidth,offsetWidth,scrollHeight
  • SVN版本回退
  • IDEA关联Tomcat
  • MongoDB mongoose 的 save、insert 和 create 方法的比较
  • Maven安装使用
  • 微信第三方开放平台接入本地消息事件接口报错问题java.security.InvalidKeyException: Illegal key size
  • 如何只修改obsidian图片链接为markdown
  • AI不可尽信
  • [C++]使用纯opencv部署yolov11旋转框目标检测
  • Python入门--函数
  • winFrom界面无法打开
  • 【Linux】Ubuntu20.04上使用RabbitVCS的图形化SVN
  • DMA直接存储器存取
  • java计算机毕设课设—坦克大战游戏
  • Vue入门-指令学习-v-on
  • Maven的生命周期与依赖作用域介绍
  • Django学习笔记四:urls配置详解
  • NIO的callback调用方式
  • 百度文心智能体平台开发萌猫科研加油喵
  • Hive数仓操作(十六)