题目:
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
题目数据保证答案符合 32 位带符号整数范围。
示例 :
输入:s = "rabbbit", t = "rabbit" 输出:3 解释: 如下图所示, 有 3 种可以从 s 中得到 "rabbit" 的方案。 ra b bbit rab b bit rabb b it
思路:
动态规划,现在都不考虑效率,能懂就行了。
复杂度:
时间:双重循环O(m*n)。
空间:O(m*n)。
代码:
public int numDistinct(String s, String t) {
int m = s.length();
int n = t.length();
//dp[i][j]存的是到i为止的s包含到j为止的t的个数
int dp[][] = new int [m+1][n+1];
//确定递推公式
//如果s[i-1]和t[j-1]匹配了,并且就用s[i-1]和t[j-1]匹配的话,那么个数就是dp[s-1][t-1]
//也可以选择不用s[i-1]匹配,这时候个数就是dp[i-1][j] dp = 两者和
//不过不匹配,则只能舍去s[i-1]
//从后往前推稍微好理解点
//初始化,两者都是0,大家一样,只有一个
dp[0][0] = 1;
for(int i = 0;i<m;++i){
//初始化所有没有t的情况
dp[i+1][0] = 1;
for(int j = 0;j<=i&&j<n;++j){
if(s.charAt(i) == t.charAt(j)){
dp[i+1][j+1] = dp[i][j] + dp[i][j+1];
}else{
dp[i+1][j+1] = dp[i][j+1];
}
}
}
return dp[m][n];
}