Description
Given two strings s and t, return the number of distinct subsequences of s which equals t.
The test cases are generated so that 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.
**rabb**b**it**
**ra**b**bbit**
**rab**b**bit**
Example 2:
Input: s = “babgbag”, t = “bag”
Output: 5
Explanation:
As shown below, there are 5 ways you can generate “bag” from s.
**ba**b**g**bag
**ba**bgba**g**
**b**abgb**ag**
ba**b**gb**ag**
babg**bag**
Constraints:
1 <= s.length, t.length <= 1000
s
andt
consist of English letters.
Code
Top-Down DP with memo
Time Complexity: , Space Complexity:
class Solution {
public:
int numDistinct(string s, string t) {
int m = s.length(), n = t.length();
vector<vector<int>> memo(m + 1, vector<int>(n + 1, -1));
int j = 0;
int res = 0;
for(int i = 0; i < s.length(); i++) {
if(s[i] == t[j])
res += dfs(s, t, i + 1, j + 1, memo);
}
return res;
}
int dfs(string& s, string& t, int i, int j, vector<vector<int>>& memo) {
if(memo[i][j] != -1)
return memo[i][j];
if(j == t.length())
return memo[i][j] = 1;
if(i >= s.length())
return memo[i][j] = 0;
int res = 0;
for(int k = i; k < s.length(); k++) {
if(s[k] == t[j])
res += dfs(s, t, k + 1, j + 1, memo);
}
return memo[i][j] = res;
}
};
Bottom Up
Time Complexity: , Space Complexity:
dp[i][j]
: the number of distinct subsequences of s[0:i]
which equals t[0:j]
.
Base case:
// base case
for(int j = 0; j <= m; j++)
dp[j][0] = 1;
考慮下面的例子,最左邊那排都是 1 ,因為這排代表的是當 s 某個 index 和 t 的第一個 index 的 char 相等時,會產生的 distinct subsequence 的數量。
以 babgb 和 b 一組為例,要計算的是 dp[5][1]
,因為 b 都相等,因此要 + 1,也就是 dp[4][0]
的值,但同時,先前已經計算好 babg 和 b 會有多少個 distinct subsequence 了,也就是 dp[4][1] = 2
,所以說 dp[5][1] = 2 + 1 = 3
。
s = "babgbag", t = "bag"
b a g
------------
|1 0 0 0
b |1 1 0 0
a |1 1 1 0
b |1 2 1 0
g |1 2 1 1
b |1 3 1 1
a |1 3 4 1
g |1 3 4 5
t 不可以被 skip,s 可以,不 match 就跳過即可。
class Solution {
public:
int numDistinct(string s, string t) {
int m = s.length(), n = t.length();
vector<vector<unsigned>> dp(m + 1, vector<unsigned>(n + 1, 0));
// base case
for(int j = 0; j <= m; j++)
dp[j][0] = 1;
for(int i = 1; i < m + 1; i++) {
for(int j = 1; j < n + 1; j++) {
dp[i][j] = dp[i - 1][j] + ((s[i - 1] == t[j - 1]) ? dp[i - 1][j - 1] : 0);
dp[i][j] %= INT_MAX;
}
}
return dp[m][n];
}
};