Distinct Subsequences
Given a string S and a string T, count the number of distinct subsequences of T in S.
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
.
DP,化歸為二維地圖的走法問題。
r a b b i t
1 0 0 0 0 0 0
r 1
a 1
b 1
b 1
b 1
i 1
t 1
設矩陣transArray,其中元素transArray[i][j]為S[0,...,i]到T[0,...,j]有多少種轉換方式。
問題就轉為從左上角只能走對角(匹配)或者往下(刪除字符),到右下角一共有多少種走法。
transArray[i][0]初始化為1的含義是:任何長度的S,如果轉換為空串,那就只有刪除全部字符這1種方式。
當S[i-1]==T[j-1],說明可以從transArray[i-1][j-1]走對角到達transArray[i][j](S[i-1]匹配T[j-1]),此外還可以從transArray[i-1][j]往下到達transArray[i][j](刪除S[i-1])
當S[i-1]!=T[j-1],說明只能從transArray[i-1][j]往下到達transArray[i][j](刪除S[i-1])
class Solution { public: int numDistinct(string S, string T) { int m = S.size(); int n = T.size(); vector<vector<int> > path(m+1, vector<int>(n+1, 0)); for(int i = 0; i < m+1; i ++) path[i][0] = 1; for(int i = 1; i < m+1; i ++) { for(int j = 1; j < n+1; j ++) { if(S[i-1] == T[j-1]) path[i][j] = path[i-1][j-1] + path[i-1][j]; else path[i][j] = path[i-1][j]; } } return path[m][n]; } };