子序列的个数
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。
(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
题目数据保证答案符合 32 位带符号整数范围。

提示:
0 <= s.length, t.length <= 1000 s 和 t 由英文字母组成
思路
- 确定dp数组(dp table)以及下标的含义
dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。

- 确定递推公式
这一类问题,基本是要分析两种情况
- s[i - 1] 与 t[j - 1]相等
- s[i - 1] 与 t[j - 1] 不相等
当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。
一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。
一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。

- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组

public int numDistinct(String s, String t) {
//dp[i][j] 0...i,0...j 的个数
//dp[i-1][j] no i. 0...i-1,0...j
//dp[i-1][j-1] yes i,0...i-1,0..j-1 condition s[i]=t[j]
// dp[i][0]=1 ,dp[0][j]=0
char[] S=s.toCharArray();
char[] T=t.toCharArray();
int n=s.length();
int m=t.length();
int[][] dp=new int[n+1][m+1];
for(int i=0;i<=n;i++){
dp[i][0]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=dp[i-1][j];
if(S[i-1]==T[j-1]){
dp[i][j]+=dp[i-1][j-1];
}
}
}
return dp[n][m];
}

浙公网安备 33010602011771号