判断2个字符串有多少种匹配方法

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).

Example

Given S = "rabbbit", T = "rabbit", return 3.

 

还是如何定义状态的问题。

学会如何去重新定义一个问题,这里描述的是用S去匹配T有多少种方法。也就是用S[0....S.len-1]去匹配T[0.....T.len-1]有多少种方法。

所以,可以定义状态dp[i][j]表示,用S[0~i]去匹配T[0~j]有多少种方法,dp[S.len-1][T.len-1]即为所求。

 

接下来讨论状态转移问题。

dp[i][j] 可由dp[i-1][j-1]和dp[i][j-1]得到。为什么呢?针对s[i]和t[i]可以进行如下讨论:

① 若s[i] != t[i], 不用说,dp[i][j] = dp[i][j-1]

② 若s[i] == t[j],可以选择用s[i] 去匹配 t[j], 也可以选择不匹配。此时,  dp[i][j] = dp[i-1][j-1] + dp[i][j-1]

public int numDistinct(String S, String T) {
      
        if(S == null || (S.length() == 0 && T.length() != 0) || T == null  || (T.length() > S.length()))            return 0;
        
        if(S.length() != 0 && T.length() == 0)
            return 1;
            
        int lens = S.length();
        int lent = T.length();
        int[][] dp = new int[lens][lent];
        
        dp[0][0] = S.charAt(0) == T.charAt(0) ? 1 : 0;
        
        for(int i = 1; i < lens; i++){
            if(S.charAt(i) == T.charAt(0))
                dp[i][0] = dp[i-1][0] + 1;
            else
                dp[i][0] = dp[i-1][0];
        }
        
        for(int i = 1; i < lens; i++)
            for(int j = 1; j < lent; j++){
                if(S.charAt(i) == T.charAt(j))
                    dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                else
                    dp[i][j] = dp[i-1][j];
            }
            
        return dp[lens-1][lent-1];
    }

  

posted @ 2017-05-16 23:24  贾斯彼迭  阅读(497)  评论(0编辑  收藏  举报