You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
^^^
class Solution {
public:
int numDistinct(string s, string t) {
if(t.size() > s.size()) return 0;
if(t.size()== s.size()) return s==t;
vector < long> dp(t.size()+1,0);
dp[0] = 1;
for(int i = 0; i < s.size(); ++i){
for(int j =static_cast(t.size())-1; j>=0; --j){
//dp[j] means number of subsequence that has matched j char in t, need to compare with t[j]
if(t[j]==s[i]){
dp[j+1] += dp[j];//use this character, so dp[j+1] should be modified
//at the same time keep dp[j] unchanged, which means skip this character
}
}
}
return dp.back();
}
};
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:
Example 2:
看到有关字符串的子序列或者配准类的问题,首先应该考虑的就是用动态规划 Dynamic Programming 来求解,这个应成为条件反射。而所有 DP 问题的核心就是找出状态转移方程,想这道题就是递推一个二维的 dp 数组,其中 dp[i][j] 表示s中范围是 [0, i] 的子串中能组成t中范围是 [0, j] 的子串的子序列的个数。下面我们从题目中给的例子来分析,这个二维 dp 数组应为:
首先,若原字符串和子序列都为空时,返回1,因为空串也是空串的一个子序列。若原字符串不为空,而子序列为空,也返回1,因为空串也是任意字符串的一个子序列。而当原字符串为空,子序列不为空时,返回0,因为非空字符串不能当空字符串的子序列。理清这些,二维数组 dp 的边缘便可以初始化了,下面只要找出状态转移方程,就可以更新整个 dp 数组了。我们通过观察上面的二维数组可以发现,当更新到 dp[i][j] 时,dp[i][j] >= dp[i][j - 1] 总是成立,再进一步观察发现,当 T[i - 1] == S[j - 1] 时,dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1],若不等, dp[i][j] = dp[i][j - 1],所以,综合以上,递推式为:
dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0)
根据以上分析,可以写出代码如下:
Github 同步地址:
#115
参考资料:
https://leetcode.com/problems/distinct-subsequences/
https://leetcode.com/problems/distinct-subsequences/discuss/37327/Easy-to-understand-DP-in-Java
https://leetcode.com/problems/distinct-subsequences/discuss/37412/Any-better-solution-that-takes-less-than-O(n2)-space-while-in-O(n2)-time
LeetCode All in One 题目讲解汇总(持续更新中...)
The text was updated successfully, but these errors were encountered: