zoukankan      html  css  js  c++  java
  • leetcode -day 15 Distinct Subsequences

    1、
    

    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.

    分析:此题乍一看看不明确啥意思,后面慢慢理解。就是说T是S的子串,这里的子串是说原字符串删除某些字符后剩余字符的组合,题目是S中通过删除操作获得子串T的数目。如样例中的第一个为删掉第一个b,第二个为删除第二个b,第三个为删除第三个b,因此数量为3.

    首先想到的方法是回溯法。可是遇到长串时超时。里面包括太多反复子问题。

    代码例如以下:Time Limit Exceeded

    class Solution {
    public:
        int numDistinct(string S, string T) {
            num = 0;
            if(S.length() < T.length()){
                return num;
            }
            numDistinctCore(S,T,0,0);
            return num;
        }
        void numDistinctCore(string& S,string& T, int si, int tj){
            int slen = S.length();
            int tlen = T.length();
            if(slen-si < tlen -tj){
                return;
            }
            if(tj == tlen){
                ++num;
            }
            for(int i = si; i<slen; ++i){
                if(S[i] == T[tj]){
                    numDistinctCore(S,T,i+1, tj+1);
                }
            }
        }
        int num;
    };

    考虑到回溯法子问题反复求解。想到利用动态规划的方法。此题有些像求最大公共字串,可是须要改动一下,寻找子问题。

    设dp[i][j]为S字符串截止到i时。能将S前面字符串能转换为T截止到j的子串的转换次数。求dp[i][j]时。一种方法转换时即删除S[i],变回S[i-1][j]的问题。还有一种方法。假设S[i] == T[j]。则转换为dp[i-1][j-1]的问题。

    即为同样时为 dp[i][j] = dp[i-1][j] + dp[i-1][j-1] 。不同一时候为 dp[i][j] = dp[i-1][j] 

    Accepted

    class Solution {
    public:
        int numDistinct(string S, string T) {
            int slen = S.length();
            int tlen = T.length();
            if(slen < tlen){
                return 0;
            }
            int **dp = new int*[slen+1];
            for(int i=0; i<slen+1; ++i){
                dp[i] = new int[tlen+1];
                dp[i][0] = 1;
            }
            for(int j=1; j<tlen+1; ++j){
                dp[0][j] = 0;
            }
            for(int i=1; i<slen+1; ++i){
                for(int j=1; j<tlen+1; ++j){
                    int temp = dp[i-1][j];
                    if(S[i-1] == T[j-1]){
                        temp += dp[i-1][j-1];
                    }
                    dp[i][j] = temp;
                }
            }
            int result = dp[slen][tlen];
            for(int i=0; i<slen+1; ++i){
                delete[] dp[i];
            }
            delete[] dp;
            return result;
        }
       
    };

  • 相关阅读:
    OleDbCommand 的用法
    递归求阶乘
    C#重写窗体的方法
    HDU 5229 ZCC loves strings 博弈
    HDU 5228 ZCC loves straight flush 暴力
    POJ 1330 Nearest Common Ancestors LCA
    HDU 5234 Happy birthday 01背包
    HDU 5233 Gunner II 离散化
    fast-IO
    HDU 5265 pog loves szh II 二分
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/9998983.html
Copyright © 2011-2022 走看看