LeetCode OJ-- Distinct Subsequences ** 递推

https://oj.leetcode.com/problems/distinct-subsequences/

对于string S 和 T求,T 是 S的几种子串。

首先想到了递归方法,列出递归公式,奈何超时了:

如果S[sBegin] == T[tBegin] 则是 numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T);
如果不等于,则 numSubDistinct(sBegin+1,tBegin,S,T);
如果T的遍历指针到头了,则说明成功了一次匹配

class Solution {
public:
    int numDistinct(string S, string T) {
        int ans = 0;
        if(S.size()<T.size())
            return 0;
        if(S.size() == T.size())
            if(S == T)
                return 1;
            else
                return 0;
        return numSubDistinct(0,0,S,T);
    }
    int numSubDistinct(int sBegin,int tBegin,string &S,string &T)
    {
        if(tBegin== T.size())
            return 1;
        if(sBegin == S.size() && tBegin!= T.size())
            return 0;
        if(S[sBegin] == T[tBegin])
            return numSubDistinct(sBegin+1,tBegin+1,S,T) + numSubDistinct(sBegin+1,tBegin,S,T);
        else
            return numSubDistinct(sBegin+1,tBegin,S,T);
    }
};

之后,考虑用递推实现。

根据思路来说,首先想到从后往前递推,但如果从后往前可以,则从前往后也可以。

建立二维数组num[S.size()][T.size()]存这个过程中产生的中间结果。

首先定义:num[i][j]是对于S从0到 i 的子串,对于T从 0 到 j 的子串,这两个字符串,T是S的子串数。

如果S[sBegin] == T[tBegin] num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin];

如果不等于则 num[sBegin][tBegin] = num[sBegin-1][tBegin];

根据公式,考虑到进行两层循环,
但是循环之前需要初始化

class Solution {
public:
    int numDistinct(string S, string T) {
        int ans = 0;
        if(S.size()<T.size())
            return 0;
        if(S.size() == T.size())
            if(S == T)
                return 1;
            else
                return 0;

        vector<vector<int> > num;
        num.resize(S.size());
        for(int i = 0;i<S.size();i++)
            num[i].resize(T.size());

        //initialize
        if(S[0] == T[0])
            num[0][0] = 1;
        else
            num[0][0] = 0;
        for(int i = 1;i<S.size();i++)
        {
            if(S[i] == T[0])
                num[i][0] = num[i-1][0] + 1;
            else
                num[i][0] = num[i-1][0];
        }

        for(int j = 1;j<T.size();j++)
        {
            num[0][j] = 0;
        }

        for(int sBegin = 1;sBegin<S.size();sBegin++)
            for(int tBegin = 1;tBegin<T.size();tBegin++)
            {
                if(S[sBegin] == T[tBegin])
                    num[sBegin][tBegin] = num[sBegin-1][tBegin-1] + num[sBegin-1][tBegin];
                else
                    num[sBegin][tBegin] = num[sBegin-1][tBegin];
            }
        
        return num[S.size()-1][T.size()-1];
    }
};
原文地址:https://www.cnblogs.com/qingcheng/p/3817175.html