【问题标题】:Given a string S and a string T, count the number of distinct subsequences of T in S给定一个字符串 S 和一个字符串 T,计算 S 中 T 的不同子序列的数量
【发布时间】:2014-09-15 04:16:03
【问题描述】:

大家好:有人可以向我解释一下这个算法是如何工作的吗?我无法理解机制。谢谢。

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

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

这是一个例子: S = “兔子”,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()];
}

【问题讨论】:

  • 您可能会在 cs.stackexchange.com 或programmers.stackexchange.com 上得到更好的回应
  • 用你的兔子例子试一试。

标签: java algorithm


【解决方案1】:

上面的DP解使用O(m*n)空间,其中m是S的长度,n是T的长度。下面是只有O(n)空间的解。

public class Solution {  
    public int numDistinct(String s, String t) {  
        if(s == null || t == null || t.length() == 0) return 0;  
        int[] dp = new int[t.length()];  

        for(int i = 0; i<s.length(); i++){  
            char c = s.charAt(i);  
            for(int j=dp.length-1; j>=0; j--){  
                if(c == t.charAt(j)){  
                    dp[j] = dp[j] + (j!=0?dp[j-1]: 1);  
                }  
            }  
        }  
        return dp[t.length()-1];  
    }  
}  

来自this page

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-02
      • 2016-11-24
      • 2014-09-10
      • 2021-09-10
      • 2021-10-04
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多