描述:
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).
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
^^^
就是再给定的一个字符串寻找可以有多少种组合来构成目标字符串
My solution is using O(n^2) space and running in O(n^2) time. I wonder is there a better way to do that which consumes less memory? I guess run time could not be improved though. Any thought/input would be highly appreciated, thanks!
注意的地方和上次dp问题leetcode97差不多,虽然都是hard难度,但都是蛮好入手的
/**
* Solution (DP):
* We keep a m*n matrix and scanning through string S, while
* m = T.length() + 1 and n = S.length() + 1
* and each cell in matrix Path[i][j] means the number of distinct subsequences of
* T.substr(1...i) in S(1...j)
*
* Path[i][j] = Path[i][j-1] (discard S[j])
* + Path[i-1][j-1] (S[j] == T[i] and we are going to use S[j])
* or 0 (S[j] != T[i] so we could not use S[j])
* while Path[0][j] = 1 and Path[i][0] = 0.
*/
int numDistinct(string S, string T) {
int m = T.length();
int n = S.length();
if (m > n) return 0; // impossible for subsequence
vector<vector<int>> path(m+1, vector<int>(n+1, 0));
for (int k = 0; k <= n; k++) path[0][k] = 1; // initialization
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= m; i++) {
path[i][j] = path[i][j-1] + (T[i-1] == S[j-1] ? path[i-1][j-1] : 0);
}
}
return path[m][n];
}
it only depends on previous state, so it can remove one dimension.
class Solution {
public:
int numDistinct(string s, string t) {
int m = s.length();
int n = t.length();
if (m < n) return 0;
vector<int> dp (n+1,0);
for (int i = 0; i <= m; ++i) {
for (int j = n; j >= 0; --j) {
if (j == 0)
dp[j] = 1;
else if (i == 0)
dp[j] = 0;
else {
dp[j] = dp[j] + (s[i-1] == t[j-1]? dp[j-1]: 0);
}
}
}
return dp[n];
}
};