当前位置:网站首页>不同的子序列问题I
不同的子序列问题I
2022-06-29 00:46:00 【GreyZeng】
不同的子序列问题I
作者:Grey
原文地址: 不同的子序列问题I
题目链接
暴力解法
定义递归函数
int process(char[] str, char[] t, int i, int j)
递归函数表示:str从i一直到最后,生成的序列可以匹配多少个t从j往后生成的字符串
所以process(str,t,0,0)得到的结果就是答案。
接下来考虑递归函数的base case,
if (j == t.length) {
// 表示str已经把t整个都搞定了,返回1,说明得到了一种情况
return 1;
}
// 到了这里,说明t还没到头
if (i == str.length) {
// str已经没有字符串了,t又没到头,所以,无法匹配
return 0;
}
接下来是普遍位置,考虑str[i]是否参与匹配来决定下一步的操作,注:str[i]如果要参与匹配,则必须满足str[i] == t[j]。
// str[i]位置不参与匹配
int ans = process(str, t, i + 1, j);
if (str[i] == t[j]) {
// str[i]参与,必须满足str[i] == t[j]
ans += process(str, t, i + 1, j + 1);
}
完整代码如下
public static int numDistinct(String s, String t) {
if (s.length() < t.length()) {
return 0;
}
return process(s.toCharArray(), t.toCharArray(), 0, 0);
}
// str[0....结尾]搞定t[0....结尾]
public static int process(char[] str, char[] t, int i, int j) {
if (j == t.length) {
// 全部搞定了
return 1;
}
if (i == str.length) {
// 没有了,搞不定
return 0;
}
// 不用i位置的去搞定
int ans = process(str, t, i + 1, j);
if (str[i] == t[j]) {
ans += process(str, t, i + 1, j + 1);
}
return ans;
}
这个暴力解法在LeetCode上直接超时。
动态规划
二维数组
根据暴力方法,可以得到,递归函数只有两个可变参数,所以定义二维dp,dp的含义和递归函数的含义保持一致。所以dp[0][0]就是答案。
int m = str.length;
int n = target.length;
int[][] dp = new int[m + 1][n + 1];
根据暴力方法
if (j == t.length) {
// 全部搞定了
return 1;
}
if (i == str.length) {
// 没有了,搞不定
return 0;
}
可以得到dp的最后一行都是1,即
for (int i = 0; i < m + 1; i++) {
dp[i][n] = 1;
}
接下来考虑普遍的dp[i][j],根据暴力方法
int ans = process(str, t, i + 1, j);
if (str[i] == t[j]) {
ans += process(str, t, i + 1, j + 1);
}
可以得到,dp[i][j]依赖dp[i+1][j]和dp[i+1][j+1](需要满足str[i] == t[j])位置的值。
所以
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
dp[i][j] = dp[i + 1][j] + (str[i] == target[j] ? dp[i + 1][j + 1] : 0);
}
}
完整代码
public static int numDistinct(String s, String t) {
if (s.length() < t.length()) {
return 0;
}
char[] str = s.toCharArray();
char[] target = t.toCharArray();
int m = str.length;
int n = target.length;
int[][] dp = new int[m + 1][n + 1];
for (int i = 0; i < m + 1; i++) {
dp[i][n] = 1;
}
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
dp[i][j] = dp[i + 1][j] + (str[i] == target[j] ? dp[i + 1][j + 1] : 0);
}
}
return dp[0][0];
}
时间复杂度O(m*n),其中m和n分别是s和t的长度。
空间复杂度O(m*n),其中m和n分别是s和t的长度。
一维数组
通过分析上述动态规划的解法,我们可得到一个结论,二维dp的计算顺序是从最后一行到第一行,且当前行只依赖上一行有限几个位置的信息,所以,我们可以将上述二维表简化成一维表,定义
int m = str.length;
int[] dp = new int[n + 1];
通过一维表的从最后一行到第一行的滚动更新,来得到第一行的值,完整代码如下
public static int numDistinct(String s, String t) {
if (s.length() < t.length()) {
return 0;
}
char[] str = s.toCharArray();
char[] target = t.toCharArray();
int m = str.length;
int n = target.length;
int[] dp = new int[n + 1];
dp[n] = 1;
for (int i = m - 1; i >= 0; i--) {
// 这里要注意,从左往右
for (int j = 0; j <= n - 1; j++) {
dp[j] += (str[i] == target[j] ? dp[j + 1] : 0);
}
}
return dp[0];
}
时间复杂度O(m*n),其中m和n分别是s和t的长度。
空间复杂度O(n),其中n是t的长度。
更多
边栏推荐
- [MCU club] design of blind water cup based on MCU [simulation design]
- PR 2021 quick start tutorial, how to use audio editing in PR?
- Differences among VaR, let and Const
- Excel使用过程中的参考资料
- [image denoising] matlab code for removing salt and pepper noise based on fast and effective multistage selective convolution filter
- 请问同花顺上开户安全吗
- Cross domain problem of canvas drawing caused by background image cache
- 学习通否认 QQ 号被盗与其有关:已报案;iPhone 14 量产工作就绪:四款齐发;简洁优雅的软件早已是明日黄花|极客头条
- MySQL 8.0 above reporting 2058 solution
- [MCU club] design of classroom number detection based on MCU [physical design]
猜你喜欢

Reprint: VTK notes - clipping and segmentation - irregular closed loop clipping -vtkselectpolydata class (black mountain old demon)
![[image denoising] matlab code for removing salt and pepper noise based on fast and effective multistage selective convolution filter](/img/7b/f9cea5dfe6831f5f226b907e2095eb.jpg)
[image denoising] matlab code for removing salt and pepper noise based on fast and effective multistage selective convolution filter

Remove HTML tags from Oracle

滑环的基本结构及工作原理分析

企业和IT领导者对创新的误解

Difference between applying for trademark in the name of individual and company

What is redis

HandlerThread使用及原理

Breadth first search to catch cattle

Document management.
随机推荐
Nodejs installation and download
深度优先搜索实现抓牛问题
Install MySQL on Windows platform (with Navicat premium 12 "using" tutorial)
【leetcode】1719. Number of schemes for reconstructing a tree
旋转接头安装使用注意事项
Cross domain problem of canvas drawing caused by background image cache
Ensemble de données sur les visages masqués et méthode de génération des visages masqués
Getting started with SQL
How to mount FSS object storage locally
大智慧上开户是安全的吗
毕业三年的25岁码农总结
Notes on the infrastructure of large websites
Excel使用过程中的参考资料
Introduction to JVM working principle
戴口罩人脸数据集和戴口罩人脸生成方法
同期群分析是什么?教你用 SQL 来搞定
How to carry token authentication in websocket JS connection
分析框架——用户体验度量数据体系搭建
利用verilogA模块采样
运营级智慧校园系统源码 智慧校园小程序源码+电子班牌+人脸识别系统