zoukankan      html  css  js  c++  java
  • Distinct Subsequences

    Dynamic Programming

    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.

    题目大意:删除S中某些位置的字符可以得到T,总共有几种不同的删除方法

    设S的长度为lens,T的长度为lent

    算法1:递归解法,首先,从个字符串S的尾部开始扫描,找到第一个和T最后一个字符相同的位置k,那么有下面两种匹配:a. T的最后一个字符和S[k]匹配,b. T的最后一个字符不和S[k]匹配。a相当于子问题:从S[0...lens-2]中删除几个字符得到T[0...lent-2],b相当于子问题:从S[0...lens-2]中删除几个字符得到T[0...lent-1]。那么总的删除方法等于a、b两种情况的删除方法的和。递归解法代码如下,但是通过大数据会超时:

    class Solution {
    public:
        int numDistinct(string S, string T) {
            // IMPORTANT: Please reset any member data you declared, as
            // the same Solution instance will be reused for each test case.
            return numDistanceRecur(S, S.length()-1, T, T.length()-1);
        }
        int numDistanceRecur(string &S, int send, string &T, int tend)
        {
            if(tend < 0)return 1;
            else if(send < 0)return 0;
            while(send >= 0 && S[send] != T[tend])send--;
            if(send < 0)return 0;
            return numDistanceRecur(S,send-1,T,tend-1) + numDistanceRecur(S,send-1,T,tend);
        }
    };

    参考:http://www.cnblogs.com/TenosDoIt/p/3440022.html

    http://yutianx.info/blog/2014/09/25/leetcode-distinct-subsequences.html

    遇到这种两个串的问题,很容易想到DP。但是这道题的递推关系不明显。可以先尝试做一个二维的表int[][] dp,用来记录匹配子序列的个数(以S="rabbbit",T = "rabbit"为例):

        r a b b b i t

      1 1 1 1 1 1 1 1

    0 1 1 1 1 1 1 1

    a 0 1 1 1 1 1 1

    b 0 0 2 3 3 3

    b 0 0 0 0 3 3 3

    i 0 0 0 0 0 0 3 3

    t 0 0 0 0 0 0 0 3  

    从这个表可以看出,无论T的字符与S的字符是否匹配,dp[i][j] = dp[i][j - 1].就是说,假设S已经匹配了j - 1个字符,得到匹配个数为dp[i][j - 1].现在无论S[j]是不是和T[i]匹配,匹配的个数至少是dp[i][j - 1]。除此之外,当S[j]和T[i]相等时,我们可以让S[j]和T[i]匹配,然后让S[j - 1]和T[i - 1]去匹配。所以递推关系为:

    dp[0][0] = 1; // T和S都是空串.

    dp[0][1 ... S.length() - 1] = 1; // T是空串,S只有一种子序列匹配。

    dp[1 ... T.length() - 1][0] = 0; // S是空串,T不是空串,S没有子序列匹配。

    dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0).1 <= i <= T.length(), 1 <= j <= S.length()

    实现代码:

    #include<iostream>
    #include<string>
    using namespace std;
    
    class Solution {
    public:
        int numDistinct(string S, string T) {
            int slen=S.length();
            int tlen=T.length();
            if(tlen==0)
                return 1;
            if(slen==0&&tlen)
                return 0;
            int dp[slen+1][tlen+1];
            dp[0][0]=1;
            int i,j;
            for(i=1;i<=slen;i++)
                dp[i][0]=1;
            for(i=1;i<=tlen;i++)
                dp[0][i]=0;
            for(i=1;i<=slen;i++)
            {
                for(j=1;j<=tlen;j++)
                {
                    if(S[i-1]==T[j-1])
                        dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
                    else
                        dp[i][j]=dp[i-1][j];
                }
            }
            return dp[slen][tlen];
        }
    };
    
    int main()
    {
        Solution s;
        string S="rabbbit";
        string T="rabbit";
        cout<<s.numDistinct(S,T)<<endl;
    }
  • 相关阅读:
    SpringMVC @PathVariable注解
    Spring REST
    SpringMVC @RequestMapping注解详解
    SpringMVC入门示例
    分布式系统中的幂等性
    常见性能优化策略的总结
    算法(Algorithms)第4版 练习 2.2.5
    算法(Algorithms)第4版 练习 2.2.23
    算法(Algorithms)第4版 练习 2.2.11(最终)
    算法(Algorithms)第4版 练习 2.2.11(3)
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4117925.html
Copyright © 2011-2022 走看看