[LeetCode] Distinct Subsequences

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

Here is an example:
S = "rabbbit", T = "rabbit"

Return 3.

Hide Tags
 Dynamic Programming String
 
 
方法一:dfs,逐个字符串比较,大数据超时,
class Solution {
    int m_cnt;
public:
    void dfs(const string & s, const string & t, int idx1, int idx2)
    {   
        if(idx2 == t.size())
        {   
            m_cnt++;
            return;
        }   

        if(idx1 == s.size())
            return;

        for(int i = idx1; i < s.size(); i++)
        {   
            if(s[i] == t[idx2])
                dfs(s, t, i+1, idx2+1);
        }   
    }   

    int numDistinct(string S, string T) {
        m_cnt = 0;
        dfs(S,T,0,0);
        return m_cnt;
    }   
};

方法二:dp

 设状态为 f(i, j),表示 T[0,i-1] 在 S[0,j-1] 里出现的次数。

如果T[i] != S[j],那么 f[i][j] = f[i][j-1] 意思就是和  T[0,i-1] 在 S[0,j-1] 里出现的次数相同。

如果T[i] == S[j],那么 f[i][j] = f[i][j-1] + f[i-1][j-1] 

  两种方法:t[i]是来源于s[j], 有 f[i-1][j-1] 种

         t[i]是不来源于s[j],而是来源于s[0~i-1], 有 f[i][j-1] 种

 

 时间复杂度O(m*n),空间O(m*n),不过可以用滚动数组,优化成O(m)
class Solution {
public:

    int numDistinct(string s, string t) {
        vector<int> tmp(s.size() + 1, 0);
        vector<vector<int> > f(t.size()+1, tmp);

        //f[i][j] indicates nums that t[0,i-1] was converted by s[0,j-1]

        f[0][0] = 1; // null to null, only have one way

        for(int i = 1; i < s.size(); i++)// there is only one way that any string changed to null
            f[0][i] = 1;

        for(int i = 1; i < t.size(); i++)// there is no way that null to any string
            f[i][0] = 0;

        for(int j = 1; j <= s.size(); j++)
        {
            for(int i = 1; i <= t.size(); i++)
            {
                if(i > j)
                    f[i][j] = 0;
                else
                {
                    if(t[i-1] == s[j-1])
                        f[i][j] = f[i-1][j-1] + f[i][j-1];
                    else
                        f[i][j] = f[i][j-1];
                }
            }
        }
        return f[t.size()][s.size()];

    }
};
       
 
 
原文地址:https://www.cnblogs.com/diegodu/p/4414517.html