代码随想录算法训练营第五十五天|392.判断子序列、115.不同的子序列
392.判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"
是"abcde"
的一个子序列,而"aec"
不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
示例 1:
输入:s = "abc", t = "ahbgdc"
输出:true
题解:和最长相同子序列的思路是一样的,如果相同子序列的长度等于短的那个字符串的话,它就是另一个字符串的子序列
-
dp[i]j :以 i-1 和 j-1 为结尾的字符串的最长相同子序列的长度
-
递推公式:
字符相等:dp[i]j=dp[i-1]j-1+1
字符不相等:dp[i]j]=dp[i][j-1 (只有长的那个字符串可以删除字符)
-
初始化:初始化为0
-
遍历顺序:从小到大
-
打印dp数组
代码:
class Solution {
public boolean isSubsequence(String s, String t) {
int len1=s.length()+1;
int len2=t.length()+1;
int [][] dp=new int[len1][len2];
for(int i=1;i<len1;i++){
for(int j=1;j<len2;j++){
if(s.charAt(i-1)==t.charAt(j-1))
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=dp[i][j-1];
}
}
return dp[len1-1][len2-1]==len1-1;
}
}
115.不同的子序列
给你两个字符串 s
和 t
,统计并返回在 s
的 子序列 中 t
出现的个数,结果需要对 109 + 7 取模。
示例 1:
输入:s = "rabbbit", t = "rabbit"
输出:3
解释:
如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。
rabbbit
rabbbit
rabbbit
题解:和上一题的差别在于 s中有多少个t。思想都是一样的,不同的是因为考虑的是有多少个,所以当两个字符串的元素相等时,s中的元素可以使用也可以不使用,两种情况的总和。另一个不同的点在于初始化,如果t是空串的话,字符串中有1个空串,反之则有0个。
代码:
class Solution {
public int numDistinct(String s, String t) {
int len1=s.length()+1;
int len2=t.length()+1;
int [][] dp=new int[len1][len2];
//如果t 为空,那么s中含有一个t
for(int i=0;i<len1;i++){
dp[i][0]=1;
}
for(int i=1;i<len1;i++){
for(int j=1;j<len2;j++){
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[len1-1][len2-1];
}
}