给定字符串S和字符串T,计算S中T的不同子序列的数量

时间:2014-09-15 04:16:04

标签: java algorithm

大家好:有人可以向我解释这个算法的工作原理吗?我无法理解这个机制。感谢。

问题:给定字符串S和字符串T,计算S中T的不同子序列的数量。

字符串的子序列是一个新字符串,它是由原始字符串形成的,删除一些(可以是无)字符,而不会干扰其余字符的相对位置。 (即“ACE”是“ABCDE”的子序列,而“AEC”不是)。

这是一个例子: S =“rabbbit”,T =“兔子”

返回3.

解决方案:

public int numDistincts(String S, String T)
{
  int[][] table = new int[S.length() + 1][T.length() + 1];

  for (int i = 0; i < S.length(); i++)
      table[i][0] = 1;

  for (int i = 1; i <= S.length(); i++) {
      for (int j = 1; j <= T.length(); j++) {
          if (S.charAt(i - 1) == T.charAt(j - 1)) {
              table[i][j] += table[i - 1][j] + table[i - 1][j - 1];
          } else {
              table[i][j] += table[i - 1][j];
          }
      }
  }

  return table[S.length()][T.length()];
}

1 个答案:

答案 0 :(得分:0)

首先,请注意+ =也可以=,因为[i] [j]的每个组合只被访问一次 - 实际上=会更好,因为它不会使用事实上,在Java中,int初始化为0。

这是一个动态编程解决方案。当你只考虑S的前i个字符和T的前i个字符时,table [i] [j]最终存储答案。

第一个循环表示如果T是零长度字符串,则S中T的唯一子序列是零长度子序列 - 其中有一个。

第二个循环将S的第i个字符与T的第j个字符进行比较,此时这些都是正在处理的短字符串的最后一个字符。如果这些不匹配S中T的唯一子序列也是S的子序列,其中最后一个非匹配字符被切断,我们已经在表[i-1] [j]中计算了这些。如果它们匹配则会有与该最后一个字符匹配的额外子序列。如果从序列中取出最后一个字符,那么你会从T的这一段中找到一个子序列,其中一个字符被删掉,与S中的一个字符匹配,其中一个字符被删掉,你已经在表[i-1] [j]中计算了它们-1] - 所以对于匹配,答案是表[i-1] [j] + table [i-1] [j-1]。

当然,最后你会发现你已经计算了表[s.length] [t.length]中全长S和T的答案