1、原题链接
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).
Here is an example:
S = "rabbbit"
, T = "rabbit"
Return 3
.
链接:https://www.nowcoder.com/questionTerminal/ed2923e49d3d495f8321aa46ade9f873
来源:牛客网
2、思路
* 思路:dp题。
* 状态定义:dp[i][j]代表s[0~j - 1]中T[0~i - 1]不同子串的个数。
* 递推关系式:S[j-1]!= T[i-1]: DP[i][j] = DP[i][j - 1] (不选择S中的s[j-1]字符)
* S[j-1]==T[i-1]: DP[i][j] = DP[i-1][j-1](选择S中的s[j-1]字符) + DP[i][j - 1](不选择S中的s[j-1]字符)
* 初始状态:第0列:DP[i][0] = 1,第0行:DP[0][j] = 0
*/
当s[j - 1] = t[i - 1]时,s[j - 1]要分两种情况,选或者不选本字符,所以是加和的关系。当s[j - 1] != t[i - 1]时,选择本字符的情况与不选择本字符情况一样dp[i][j - 1]
3、代码实现
1 class Solution { 2 public: 3 int numDistinct(string s, string t) { 4 int ss = s.size() + 1; 5 int st = t.size() + 1; 6 int dp[st][ss]; 7 memset(dp, 0, st* ss* sizeof(int)); 8 for (int i = 0; i < ss; i++) { 9 dp[0][i] = 1; 10 } 11 for (int i = 1; i < st; i++) { 12 for (int j = 1; j < ss; j ++) { 13 if (s[j - 1] == t[i - 1]) { 14 dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1]; 15 } else { 16 dp[i][j] = dp[i][j - 1]; 17 } 18 } 19 } 20 return dp[st - 1][ss - 1]; 21 } 22 };
4、优化
在使用中不难发现该dp二维数组可以降维,注意改变数组元素值时由后往前
1 class Solution { 2 public: 3 int numDistinct(string S, string T) { 4 int len=T.size(); 5 vector<int> array(len+1); 6 array[0]=1; 7 for(int i=1;i<S.size()+1;i++){ 8 for(int j=min(i,len);j>0;j--){ 9 if(S[i-1]==T[j-1]) 10 array[j]=array[j]+array[j-1]; 11 } 12 } 13 return array[len]; 14 } 15 };
5、api
6、参考牛客网 https://www.nowcoder.com/questionTerminal/ed2923e49d3d495f8321aa46ade9f873