Problem:
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
.
思路:
以题中的例子来说明,建立如下的匹配表。
1 1 0 0 0 0 0
0 1 1 0 0 0 0
0 0 1 2 0 0 0
0 0 0 1 3 0 0
0 0 0 0 3 3 0
0 0 0 0 0 0 3
这也是一个动态规划问题。
定义子问题P(i,j)为T的前i子串是S的前j子串的子序列的个数。
那么最优子结构为:
if T(i)!=S(i) then
P(i,j)=P(i,j-1)
else
P(i,j)=P(i,j-1)+P(i-1,j-1)
end
算法时间复杂度为O(N*M),其中N为S的字符长度,M为T的字符长度。
Solution:
public class Solution {
public int numDistinct(String S, String T) {
if(S==null||T==null)
return 0;
int slen = S.length();
int tlen = T.length();
if(tlen==0||slen==0)
return 0;
int[][] Match = new int[tlen][slen];
for(int i=0;i<tlen;i++)
{
for(int j=i;j<slen-tlen+i+1;j++)
{
if(S.charAt(j)==T.charAt(i))
{
if(i==0)
{
if(j==0)
Match[i][j] = 1;
else
Match[i][j] = Match[i][j-1] + 1;
}
else
{
Match[i][j] = Match[i][j-1] + Match[i-1][j-1];
}
}
else
{
if(j>0)
Match[i][j] = Match[i][j-1];
}
}
}
return Match[tlen-1][slen-1];
}
}
public int numDistinct(String S, String T) {
if(S==null||T==null)
return 0;
int slen = S.length();
int tlen = T.length();
if(tlen==0||slen==0)
return 0;
int[][] Match = new int[tlen][slen];
for(int i=0;i<tlen;i++)
{
for(int j=i;j<slen-tlen+i+1;j++)
{
if(S.charAt(j)==T.charAt(i))
{
if(i==0)
{
if(j==0)
Match[i][j] = 1;
else
Match[i][j] = Match[i][j-1] + 1;
}
else
{
Match[i][j] = Match[i][j-1] + Match[i-1][j-1];
}
}
else
{
if(j>0)
Match[i][j] = Match[i][j-1];
}
}
}
return Match[tlen-1][slen-1];
}
}