Input: s ="babgbag", t ="bag"Output: 5Explanation:
As shown below, there are 5 ways you can generate "bag" from s.babgbag
babgbag
babgbag
babgbag
babgbag
We recursively try to match each character of t with s, exploring both possibilities: using the current character of s or skipping it. Memoization avoids recomputation by storing results for subproblems.
classSolution {
public:int numDistinct(string s, string t) {
int m = s.size(), n = t.size();
vector<vector<int>> memo(m, vector<int>(n, -1));
function<int(int, int)> dfs = [&](int i, int j) ->int {
if (j == n) return1;
if (i == m) return0;
if (memo[i][j] !=-1) return memo[i][j];
int ans = dfs(i +1, j);
if (s[i] == t[j]) ans += dfs(i +1, j +1);
return memo[i][j] = ans;
};
returndfs(0, 0);
}
};
classSolution {
publicintnumDistinct(String s, String t) {
int m = s.length(), n = t.length();
Integer[][] memo =new Integer[m][n];
return dfs(s, t, 0, 0, memo);
}
privateintdfs(String s, String t, int i, int j, Integer[][] memo) {
if (j == t.length()) return 1;
if (i == s.length()) return 0;
if (memo[i][j]!=null) return memo[i][j];
int ans = dfs(s, t, i + 1, j, memo);
if (s.charAt(i) == t.charAt(j)) {
ans += dfs(s, t, i + 1, j + 1, memo);
}
memo[i][j]= ans;
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
funnumDistinct(s: String, t: String): Int {
val m = s.length
val n = t.length
val memo = Array(m) { IntArray(n) { -1 } }
fundfs(i: Int, j: Int): Int {
if (j == n) return1if (i == m) return0if (memo[i][j] != -1) return memo[i][j]
var ans = dfs(i + 1, j)
if (s[i] == t[j]) ans += dfs(i + 1, j + 1)
memo[i][j] = ans
return ans
}
return dfs(0, 0)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defnumDistinct(self, s: str, t: str) -> int:
m, n = len(s), len(t)
memo: dict[tuple[int, int], int] = {}
defdfs(i: int, j: int) -> int:
if j == n:
return1if i == m:
return0if (i, j) in memo:
return memo[(i, j)]
ans: int = dfs(i +1, j)
if s[i] == t[j]:
ans += dfs(i +1, j +1)
memo[(i, j)] = ans
return ans
return dfs(0, 0)
We use dynamic programming to count the number of ways to form the target string t as a subsequence of the source string s. For each character in s, we decide whether to match it with the current character in t or skip it, accumulating the total number of ways.
classSolution {
public:int numDistinct(string s, string t) {
int m = s.size(), n = t.size();
vector<vector<longlong>> dp(m +1, vector<longlong>(n +1, 0));
for (int i =0; i <= m; ++i) dp[i][0] =1;
for (int i =1; i <= m; ++i) {
for (int j =1; j <= n; ++j) {
dp[i][j] = dp[i-1][j];
if (s[i-1] == t[j-1])
dp[i][j] += dp[i-1][j-1];
}
}
return (int)dp[m][n];
}
};
classSolution {
publicintnumDistinct(String s, String t) {
int m = s.length(), n = t.length();
long[][] dp =newlong[m + 1][n + 1];
for (int i = 0; i <= m; i++) dp[i][0]= 1;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j]= dp[i-1][j];
if (s.charAt(i-1) == t.charAt(j-1))
dp[i][j]+= dp[i-1][j-1];
}
}
return (int)dp[m][n];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funnumDistinct(s: String, t: String): Int {
val m = s.length
val n = t.length
val dp = Array(m + 1) { LongArray(n + 1) }
for (i in0..m) dp[i][0] = 1Lfor (i in1..m) {
for (j in1..n) {
dp[i][j] = dp[i-1][j]
if (s[i-1] == t[j-1])
dp[i][j] += dp[i-1][j-1]
}
}
return dp[m][n].toInt()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defnumDistinct(self, s: str, t: str) -> int:
m, n = len(s), len(t)
dp: list[list[int]] = [[0] * (n +1) for _ in range(m +1)]
for i in range(m +1):
dp[i][0] =1for i in range(1, m +1):
for j in range(1, n +1):
dp[i][j] = dp[i-1][j]
if s[i-1] == t[j-1]:
dp[i][j] += dp[i-1][j-1]
return dp[m][n]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnnum_distinct(s: String, t: String) -> i32 {
let (m, n) = (s.len(), t.len());
let s = s.as_bytes();
let t = t.as_bytes();
letmut dp =vec![vec![0i64; n +1]; m +1];
for i in0..=m { dp[i][0] =1; }
for i in1..=m {
for j in1..=n {
dp[i][j] = dp[i-1][j];
if s[i-1] == t[j-1] {
dp[i][j] += dp[i-1][j-1];
}
}
}
dp[m][n] asi32 }
}