leecode115---dfs,string---Distinct Subsequences

 
题意:
给两个字符串s和p
判断p是不是s的子字符串,如果是的话返回是的次数。
也就是说s字符串删除掉几个字母后会不会变成p字符串
Here is an example:
S = "rabbbit", T = "rabbit"
Return 3.
可以删除掉三个不同的b仍然是成立的,所以结果是三种
 
分析
因为要返回是的次数,所以最后的结果必须是int类型的数据。
仍然是维护一个dp二维数组,其中dp[i][j]表示的意思是s字符串的i个字母删除掉某些个字母之后会变成j长度的p字符串
s1 s2 s3 s4 s5 s6 s7---
p1 p2 p3 p4
进行初始化:
1.都是0,那么结果为1。
2.如果目标p为0,也就是s全删了就变成了p,所以值为1.
3.如果s为0,p不为0,s不管怎么删都不会成为p,所以结果为0.
一般情况下将i个字符变成j个字符
对于dp[i][j]这个数的计算来说,
 
 
代码
class Solution {
    public int numDistinct(String s, String t) {
        if(s==null || t==null)return 0;
        if(s.length()<t.length())return 0;
        //新建dp数组,dp[i][j]表示的是s字符串的前i个字母,转化成t字符串的前j个字母一共有几种删除方法。
        int[][] dp = new int[s.length()+1][t.length()+1];
        dp[0][0] = 1;
        for(int i=1;i<=t.length();i++){
            dp[0][i] = 0;//如果s的字母数量是0,是不可能通过删除转化成t字符串的
        }
        for(int i=1;i<=s.length();i++){
            dp[i][0] = 1;
        }
        //一般情况就是求dp[i][j]的情况,就是s中前i个字母变成q中的前j个字母
        //计算顺序是i参数先固定。
        for(int i=1;i<=s.length();i++){
            for(int j=1;j<=t.length();j++){
                if (i < j) {
                    dp[i][j] = 0;
                    continue;
                }
                //如果i位置和j位置的字母不相同,那么相当于s字符串中新增的这个字符完全没用,意思是你不管怎么删掉这个i的字母都不会多出一种变成j的方式,因为只能够删除嘛。
                //也就是说i-1字符变成j个字符的变化方式 === i个字符变成j个字符的方式
                if(s.charAt(i-1) != t.charAt(j-1)){
                    dp[i][j] = dp[i-1][j];
                }else{
                //i位置的字符和j位置的字符如果相同的情况下
                //因为最新的这个数字相等,那么
                    dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                }
            }
        }
        return dp[s.length()][t.length()];
    }
}
posted @ 2018-08-06 20:56  buptyuhanwen  阅读(108)  评论(0编辑  收藏  举报