• [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()];
    
        }
    };
           
     
     
  • 相关阅读:
    新手Android开发:onclicklistener到底怎么用?
    Myeclipse中web project 与java project区别
    <jsp:directive.page import=""/>的用法和解释
    怎样在myeclipse下,打开已有的项目
    有史以来最简单的三层实例(C#)
    show()跟showdialog()的区别
    献给和我一样的Java初学者——用UltraEdit代替“笨重”的IDE,实现轻巧编程!
    数据库连接错误——请求失败或服务器未及时响应
    说说二级C++
    十一张图让你轻松学会用VS打包
  • 原文地址:https://www.cnblogs.com/diegodu/p/4414517.html
Copyright © 2020-2023  润新知