首页 > Python资料 博客日记
力扣115-不同的子序列(Java详细题解)
2024-09-22 11:00:05Python资料围观33次
题目链接:不同的子序列
前情提要:
因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。
dp五部曲。
1.确定dp数组和i下标的含义。
2.确定递推公式。
3.dp初始化。
4.确定dp的遍历顺序。
5.如果没有ac打印dp数组 利于debug。
每一个dp题目如果都用这五步分析清楚,那么这道题就能解出来了。
题目思路:
本题的题目描述非常清晰,返回t字符串在s字符串中出现的个数。该题与力扣392类似,力扣392中是判断t能不能在s中出现,而本题是要求t在s中出现的个数。
话不多说,直接开始我们的dp五部曲。
1.确定dp数组和i下标的含义。
因为要需要比较俩个字符串的元素,所以我们需要用一个二维dp数组来记录每一个元素比较的结果。
dp[i] [j]指的就是以i - 1为结尾的s中有以j - 1为结尾的t的个数(在s中删除元素得到t的方法数)。
至于为什么要定义i - 1,j - 1可以看看这篇力扣718-最长重复子数组(Java详细题解)-CSDN博客。
2.确定递推公式。
子序列问题都要考虑nums[i - 1] 是否等于 nums[j - 1]的情况。
-
相等的情况。
其实相等的情况还要分俩种。
-
第一种 考虑用nums[i - 1]匹配nums[j - 1]。即s不删除元素得到t的方法数。
此时dp[i] [j] = dp[i - 1] [j - 1]。因为用i - 1结尾的元素与j - 1结尾的元素匹配,而他们末尾的元素是相同的,所以s出现t的个数就由以元素前一位为结尾的dp数组决定。
-
第二种 不考虑用nums[i - 1]匹配nums[j - 1]。即s删除元素得到t的方法数。
此时dp[i] [j] = dp[i - 1] [j]。因为我们不用i - 1结尾的元素与j - 1结尾的元素匹配,所以我们就找i - 1前一个的元素与j - 1匹配 (即删除nums[i - 1]这个元素)。
这里可能有人不明白了,为什么还要考虑 不用s[i - 1]来匹配,都相同了指定要匹配啊。
例如: s:bagg 和 t:bag ,s[3] 和 t[2]是相同的,但是字符串s也可以不用s[3]来匹配,即用s[0]s[1]s[2]组成的bag。
当然也可以用s[3]来匹配,即:s[0]s[1]s[3]组成的bag。
dp[i - 1] [j]的含义就是以i - 2为结尾的s中出现以j - 1为结尾的t的个数。
总之不相等的情况递推公式为:dp[i] [j] = dp[i - 1] [j - 1] + dp[i - 1] [j];
-
-
不相等的情况
既然结尾的元素都不相等了,那我们肯定是要删除s中最后一位元素,所以dp[i] [j] = dp[i - 1] [j];
3.dp初始化。
由递推公式可知dp[i] [j]都是由dp[i - 1] [j - 1]和dp[i - 1] [j]推来的,所以在二维dp数组中就是由它的左上方和左方推来的。
所以第一列和第一排是递推的起点。
因为dp[i] [0](第一列)是指以i - 1为结尾的s中出现空串的个数。(以i - 1为结尾的s中删除元素得到t的方法数)
所以出现空串的删除元素方法只有一种,那就是全删了。
所以初始化的代码为:
for(int i = 0;i <= s.length();i ++){
dp[i][0] = 1;
}
dp[0] [i]是指空串中出现以i - 1为结尾的t的个数,毫无疑问肯定为0。
4.确定dp的遍历顺序。
由递推公式可知dp[i] [j]都是由dp[i - 1] [j - 1]和dp[i - 1] [j]推来的。
所以遍历顺序一定是从上到下 从左到右。
5.如果没有ac打印dp数组 利于debug。
最终代码:
class Solution {
public int numDistinct(String s, String t) {
//定义dp数组 以i- 1为结尾的s中有以j - 1为结尾的t的个数(在s中删除元素得到t的方法数)
int [][] dp = new int [s.length() + 1][t.length() + 1];
//dp初始化
for(int i = 0;i <= s.length();i ++){
dp[i][0] = 1;
}
//dp的遍历顺序
for(int i = 1;i <= s.length();i ++){
for(int j = 1;j <= t.length();j ++){
//dp的递推公式
if(s.charAt(i - 1) == t.charAt(j - 1)){
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}else{
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[s.length()][t.length()];
}
}
这一篇博客就到这了,如果你有什么疑问和想法可以打在评论区,或者私信我。
我很乐意为你解答。那么我们下篇再见!
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj