不同的子序列
题目:
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)
题目数据保证答案符合 32 位带符号整数范围。
示例 1:
输入:s = "rabbbit", t = "rabbit"
输出:3
示例 2:
输入:s = "babgbag", t = "bag"
输出:5
解题思路:首先从s 和 t 的最后一个字符开始思考,此时有两种情况,当两字符不相等时则需要从s[0..s.length - 2]和t[0..t.length - 1]中寻找s的子序列可以转化为 t 的个数;当两字符相等时除去前面一种情况还要再加上s[0…s.length - 2]和t[0…t.length - 2]的个数,由此可以得处状态方程即可解答
class Solution {
public int numDistinct(String s, String t) {
char[] chs = s.toCharArray(), cht = t.toCharArray();
int len1 = chs.length, len2 = cht.length;
// 数组定义:dp[i][j]表示s[0..i - 1]的子序列转化为t[0..j - 1]的个数
int dp[][] = new int[len1 + 1][len2 + 1];
// 初始化 当t是空串时,s只有一个子序列可以转化为t
for(int i = 0; i <= len1; i++) {
dp[i][0] = 1;
}
/**
状态方程:dp[i][j] = dp[i - 1][j] + (s[i - 1] == t[j - 1] ? dp[i - 1][j - 1] : 0)
**/
for(int i = 1; i <= len1; i++) {
for(int j = 1;j <= len2; j++) {
dp[i][j] = dp[i - 1][j];
if(chs[i - 1] == cht[j - 1]) {
dp[i][j] += dp[i - 1][j - 1];
}
}
}
return dp[len1][len2];
}
}