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
^^^
思路:
两种方案:1 递归;2 动态规划。
1 递归
对于字符串s来说,每次遇到和t相同的字符时都有匹配和不匹配两种选择,我们递归的查找这两种选择直到t的结尾。但是这种方法时间复杂度太高,导致超时。
void helper(string s, string t, int &result){
if (s.size() < t.size()) return;
if (t.size() == 0) {
result++;
return;
}
if (s[0] == t[0]){
string tempS = s;
string tempT = t;
tempS.erase(0, 1); tempT.erase(0, 1);
helper(tempS, tempT, result);
helper(tempS, t, result);
}
else{
string tempS = s;
tempS.erase(0, 1);
helper(tempS, t, result);
}
}
int numDistinct(string s, string t) {
int result = 0;
helper(s, t, result);
return result;
}
2 动态规划
两种动态规划的实现方案:1 二维数据记录;2 一维数组记录。
1 二维数组记录
int numDistinct2(string s, string t) {
vector<vector<int>> dp(s.size()+1, vector<int>(t.size()+1, 0));
for (int i = 0; i <= s.size(); i++) dp[i][0] = 1;
for (int i = 1; i <= t.size(); i++){
if (s[i - 1] == t[i - 1]) dp[i][i] = dp[i - 1][i - 1];
for (int j = i + 1; j <= s.size(); j++){
if (s[j - 1] == t[i - 1])
dp[j][i] = dp[j - 1][i - 1] + dp[j - 1][i];
else
dp[j][i] = dp[j - 1][i];
}
}
return dp[s.size()][t.size()];
}
2 二维数据记录
int numDistinct3(string s, string t){
vector<int> dp(s.size() + 1, 1);
for (int j = 0; j < t.size(); j++){
int pre = dp[j];
dp[j] = 0;
for (int i = j + 1; i <= s.size(); i++){
int temp = dp[i];
dp[i] = s[i - 1] == t[j] ? dp[i - 1] + pre : dp[i - 1];
pre = temp;
}
}
return dp.back();
}
纪念贴图: