将不重复出现算作子序列

时间:2018-09-01 00:50:40

标签: algorithm data-structures dynamic-programming

我正在经历geeksforgeeks的“将不重复出现作为子序列问题进行计数”。我希望了解“其他”情况。如果最后一个字符匹配,为什么没有S +的最后一个字符而没有S和T的最后两个字符的结果呢?

Input  : S = banana, T = ban
Output : 3
T appears in S as below three subsequences.
[ban], [ba  n], [b   an]

// Returns count of subsequences of S that match T 
// m is length of T and n is length of S
subsequenceCount(S, T, n, m)

//空字符串是所有子序列。    1)如果T的长度为0,则返回1。

//否则,没有字符串可以是空S的序列。    2)否则,如果S为空,则返回0。

3)如果S和T的最后一个字符不匹配,       删除S的最后一个字符并重复剩余         返回subsequenceCount(S,T,n-1,m)

4)其他(最后一个字符匹配),结果为和       两种计数。

    // Remove last character of S and recur.
    a) subsequenceCount(S, T, n-1, m) + 

    // Remove last characters of S and T, and recur.
    b) subsequenceCount(S, T, n-1, m-1)  

2 个答案:

答案 0 :(得分:1)

考虑S="banan"T="ban"的情况。最后一个字符匹配,因此在T子序列中出现的S必须是:

  • 不包括S的最后一个字符。这样可以简化为子问题S="bana"T="ban",该子问题出现了1次:“ ban a”。
  • 包括S的最后一个字符。这简化为子问题S="bana"T="ba"。这里有2个出现:“ ba na”和“ b an a ”。如果我们回到主要问题,则对应的出现是“ ba na n ”和“ b an 一个 >”。

出现的总数是两个子问题的总和。

答案 1 :(得分:0)

这可能是一个更简单的解决方案 S =“香蕉” T =“禁止”

int solve(int i, int j, string &S, string &T){
 if(j>=T.size())
    return 1;
 else if(i>=A.size() && j<T.size())
    return 0;
 int sum = 0;

 sum = solve(i+1, j, S, T);

 if(S[i] == T[j]){
   sum += solve(i+1, j+1, S, T);
 }
 return sum;
}

在此解决方案中,i代表S字符串的索引,j代表T字符串的索引。在任何状态(i, j)下,我们都有两种可能的情况,即在两个字符串的给定索引处表示的字符都匹配或不匹配。

  1. 如果字符匹配或不匹配,则必须将S字符串的char移至下一个字符,因为可以在S的下一个子部分中找到字符串T。
  2. 如果字符匹配,则移至每个字符串的下一个字符。
  3. 最后,取两个可能的递归关系之和并返回它。