题意:
给两个字符串s和p
判断p是不是s的子字符串,如果是的话返回是的次数。
也就是说s字符串删除掉几个字母后会不会变成p字符串
Here is an example:
S = "rabbbit", T = "rabbit"
Return 3.
可以删除掉三个不同的b仍然是成立的,所以结果是三种
分析
因为要返回是的次数,所以最后的结果必须是int类型的数据。
仍然是维护一个dp二维数组,其中dp[i][j]表示的意思是s字符串的i个字母删除掉某些个字母之后会变成j长度的p字符串
s1 s2 s3 s4 s5 s6 s7---
p1 p2 p3 p4
进行初始化:
1.都是0,那么结果为1。
2.如果目标p为0,也就是s全删了就变成了p,所以值为1.
3.如果s为0,p不为0,s不管怎么删都不会成为p,所以结果为0.
一般情况下将i个字符变成j个字符
对于dp[i][j]这个数的计算来说,
代码
class Solution {
public int numDistinct(String s, String t) {
if(s==null || t==null)return 0;
if(s.length()<t.length())return 0;
//新建dp数组,dp[i][j]表示的是s字符串的前i个字母,转化成t字符串的前j个字母一共有几种删除方法。
int[][] dp = new int[s.length()+1][t.length()+1];
dp[0][0] = 1;
for(int i=1;i<=t.length();i++){
dp[0][i] = 0;//如果s的字母数量是0,是不可能通过删除转化成t字符串的
}
for(int i=1;i<=s.length();i++){
dp[i][0] = 1;
}
//一般情况就是求dp[i][j]的情况,就是s中前i个字母变成q中的前j个字母
//计算顺序是i参数先固定。
for(int i=1;i<=s.length();i++){
for(int j=1;j<=t.length();j++){
if (i < j) {
dp[i][j] = 0;
continue;
}
//如果i位置和j位置的字母不相同,那么相当于s字符串中新增的这个字符完全没用,意思是你不管怎么删掉这个i的字母都不会多出一种变成j的方式,因为只能够删除嘛。
//也就是说i-1字符变成j个字符的变化方式 === i个字符变成j个字符的方式
if(s.charAt(i-1) != t.charAt(j-1)){
dp[i][j] = dp[i-1][j];
}else{
//i位置的字符和j位置的字符如果相同的情况下
//因为最新的这个数字相等,那么
dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
}
}
}
return dp[s.length()][t.length()];
}
}