动态规划
class Solution {
public int numDistinct(String s, String t) {
/**
* 结合《1143. 最长公共子序列》和《392. 判断子序列》
* dp[i][j]定义为以s[i - 1]结尾的字符串s中出现以t[j - 1]结尾的字符串t的个数
* 如果t长度为0,则肯定出现在s中,初始化为1
*/
int[][] dp = new int[s.length() + 1][t.length() + 1];
for (int i = 0; i <= s.length(); i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= s.length(); i++) {
for (int j = 1; j <= t.length(); j++) {
/**
* 如果s.charAt(i) == t.charAt(j),说明匹配成功,t是用t[j - 1]来匹配的,但s却分为两种情况
* 1、s是用s[i - 1]来匹配的,因此个数等于dp[i - 1][j - 1](注意此处求的是个数而不是长度,所以不用加1)
* 2、s使用s[i - 2]来匹配的,因为可能s[i - 2] == s[i - 1],等价于删掉s[i - 1],此时个数等于dp[i - 1][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[s.length()][t.length()];
}
}
/**
* 时间复杂度 O(n^2)
* 空间复杂度 O(n^2)
*/
https://leetcode-cn.com/problems/distinct-subsequences/