LintCode:118.不同的子序列(考点:动态规划)

描述

给出字符串S和字符串T,计算S的不同的子序列中T出现的个数。

子序列字符串是原始字符串通过删除一些(或零个)产生的一个新的字符串,并且对剩下的字符的相对位置没有影响。(比如,“ACE”“ABCDE”的子序列字符串,而“AEC”不是)。 

样例

给出S = "rabbbit", T = "rabbit"

返回 3


分析:

采用动态规划的思想,dp[i][j]表示S前i个字符中含有T前j个字符的个数,不管S[i]是否等于T[j],都有dp[i][j]=dp[i-1][j],如果S[i]==T[j],则dp[i][j]还需要加上dp[i-1][j-1]。dp[i-1][j-1]表示都往前看一位,因为最后一个字符已经满足条件。

public class Solution {
    /*
     * @param : A string
     * @param : A string
     * @return: Count the number of distinct subsequences
     */
    public int numDistinct(String S, String T) {
        // write your code here
        if(S==null||T==null)    return 0;
        int[][] dp=new int[S.length()+1][T.length()+1];  //dp[i][j]表示S的前i个字符包含T的前j个字符个数
        for(int i=0;i<=S.length();i++)
            dp[i][0]=1;
        for(int i=1;i<=S.length();i++){
            for (int j=1;j<=T.length();j++){
                //不管S[i]和T[j]相不相等,首先dp(i,j)=dp(i-1,j),如果相等的话,最后一位就不需要看了,都往前看一位。
                if(S.charAt(i-1)!=T.charAt(j-1)){
                    dp[i][j]=dp[i-1][j];
                }else{
                    dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
                }
            }
        }
        return dp[S.length()][T.length()];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/81042868