115. Distinct-Subsequences
difficulty: Hard
Given a string S and a string T, count the number of distinct subsequences of S which equals T.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE"
is a subsequence of "ABCDE"
while "AEC"
is not).
It's guaranteed the answer fits on a 32-bit signed integer.
Example 1:
Input: S = "rabbbit", T = "rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters)
rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
Example 2:
Input: S = "babgbag", T = "bag"
Output: 5
Explanation:
As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters)
babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^
Method One
class Solution {
public int numDistinct(String s, String t) {
// t 是 Pattern, 我选择让他竖着
// s 是横着的。
// 所以第一行是 1,因为 t 是 "".
int n = s.length();
int m = t.length();
int[][] dp = new int[m + 1][n + 1];
for(int j = 0; j < n; j++ ) {
dp[0][j] = 1;
}
for(int i = 0; i < m; i++ ) {
for(int j = i; j < n; j++ ) {
// 注意这个 j = i, 其实无所谓,但是这意味着,
// 如果 t 比 s 短,一定得到的是个 0.
// 第 i + 1, j + 1 收到两个贡献。
// 一个是来自 i + 1, j 的,无论 s.charAt(j) == t.charAt(i)
// 我们都有这个。比如 s = rabc, t = rab, 天然就等于 s = rab, t = rab 的结果。因为 t 已经用完了。
// 如果 s = rabb, t = rab, 我们还能加上一个来自 s = rab, t = ra, 因为我们成功给这一组续命了。
// 如果 不是 b == b, 我们就没法算上这个方向的贡献。
dp[ i + 1 ][ j + 1 ] = dp[ i + 1][ j ];
if( s.charAt(j) == t.charAt(i) ){
dp[ i + 1][j + 1 ] += dp[i][j];
}
}
}
return dp[m][n];
}
}
再来补充一点帮助理解:
class Solution {
public int numDistinct(String s, String t) {
int M = t.length();
int N = s.length();
int[][] dp = new int[M + 1][N + 1];
for (int j = 0; j <= N; j++) {
dp[0][j] = 1;
}
for (int i = 1; i <= M; i++) {
for (int j = i; j <= N; j++) {
dp[i][j] = dp[i][j - 1];
if (t.charAt(i - 1) == s.charAt(j - 1)) {
dp[i][j] += dp[i - 1][j - 1];
}
}
}
return dp[M][N];
}
}
/**
t\s ''a b a z k b z
'' 1 1 1 1 1 1 1 1
a 0 1 1 2 2 2 2 2
b 0 0 1 1 1 1 3 3
考虑
(abazk, a), (abazk, ab), (abazkb, ab)
(abazkb, ab) 收到两份贡献,
第一份来自于 (abazk, a), 这里相当于固定了最后一位相等的 b 不动。
还有一份来自于 (abazk, ab), 这里相当于我们放弃了新增的有效的 b, 把它当作一个不match的字符
这样我们就确保了没有重复的部分。
*/
Last updated
Was this helpful?