求母串中出现字串的次数

题目描述

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

字符串的子序列是由原来的字符串删除一些字符(也可以不删除)在不改变相对位置的情况下的剩余字符(例如,"ACE"is a subsequence of"ABCDE"但是"AEC"不是)
例如:

S =“rabbbit”, T =“rabbit”
返回3

分析
我们需要一个二维数组dp(i)(j)来记录长度为i的字串在长度为j的母串中出现的次数,这里长度都是从头算起的,而且遍历时,保持子串长度相同,先递增母串长度,母串最长时再增加一点子串长度重头开始计算母串。

首先我们先要初始化矩阵,当子串长度为0时,所有次数都是1,当母串长度为0时,所有次数都是0.当母串子串都是0长度时,次数是1(因为都是空,相等)。接着,如果子串的最后一个字母和母串的最后一个字母不同,说明新加的母串字母没有产生新的可能性,可以沿用该子串在较短母串的出现次数,所以dp(i)(j) = dp(i)(j-1)。如果子串的最后一个字母和母串的最后一个字母相同,说明新加的母串字母带来了新的可能性,我们不仅算上dp(i)(j-1),也要算上新的可能性。那么如何计算新的可能性呢,其实就是在既没有最后这个母串字母也没有最后这个子串字母时,子串出现的次数,我们相当于为所有这些可能性都添加一个新的可能。所以,这时dp(i)(j) = dp(i)(j-1) + dp(i-1)(j-1)。下图是以rabbbit和rabbit为例的矩阵示意图。计算元素值时,当末尾字母一样,实际上是左方数字加左上方数字,当不一样时,就是左方的数字。
求母串中出现字串的次数_第1张图片

代码

public class Solution {
    public int numDistinct(String S, String T) {
        //T字串在左,S母串在上
        //记住那一个表吧
        int m = T.length();
        int n = S.length();
        int [][] arr = new int[m+1][n+1];
        //第一行全是0:当字串T为0
        for(int j=0;j<=n;j++)
            arr[0][j] = 1;
        //每一行开始:母串
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                //两者相等
                if(T.charAt(i-1) == S.charAt(j-1))
                    arr[i][j] = arr[i-1][j-1]+arr[i][j-1];
                else
                    arr[i][j] = arr[i][j-1];
            }
        }
        return arr[m][n];
    }
}

你可能感兴趣的:(leetcode,字符串)