<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小明思考

    Just a software engineer
    posts - 124, comments - 36, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    子序列計數(shù)

    Posted on 2013-04-26 23:33 小明 閱讀(2040) 評論(1)  編輯  收藏 所屬分類: 數(shù)據(jù)結(jié)構(gòu)和算法
    問題給定兩個字符串S和T,計算S的子序列為T的個數(shù)。

    這里的字符串的子序列指的是刪除字符串的幾個字符(也可以不刪)而得到的新的字符串,但是不能改變字符的相對位置。

    比如“ACE”是“ABCDE”的子序列,但是“AEC”就不是。

    如果S=“rabbbit” T=“rabit”,有3種不同的子序列為T的構(gòu)成方法,那么結(jié)果應該返回3。

    分析:

    解法一:遞歸
    直覺的解法是使用遞歸,先在S中找到T的第一個字符,然后遞歸查找在剩余的S查找剩余的T(除去首字符)。
    如果T的長度為1,只需要計算S中一共有幾個T就可以了。
    代碼如下,非常簡潔,但是效率不高:

    public int numDistinct(String S, String T) {
            int ls = S.length();
            int lt = T.length();
            if(ls<lt){
                return 0;
            }
            
            char[] cs = S.toCharArray();
            char t0 = T.charAt(0);
            String T1 = T.substring(1);
            
            int result = 0;
            for(int i=0;i<ls;++i){
                if(cs[i]==t0){
                    if(lt>1){
                        result += numDistinct(S.substring(i+1),T1);
                    }
                    else{
                        ++result;
                    }
                }    
            }
            return result;
        }

    解法二,
    為了提高效率,很自然的想法是使用動態(tài)規(guī)劃,記錄中間狀態(tài),從而避免重復計數(shù)。

    狀態(tài)轉(zhuǎn)移方程如下,計D(m,n)為S的子串(0..m)中子序列為T(0..n)的個數(shù)。

    那么D(m,n) = D(m-1,n) if S(m)<>T(n)
                     = D(m-1,n)+D(m-1,n-1) if (S(m)=T(n) and n>0)
                     = D(m-1,n)+1 if(S(m)=T(0) and n=0)

    代碼如下:復雜度為O(mn) m,n為S和T的長度

    public int numDistinct(String S, String T) {
            int ls = S.length();
            int lt = T.length();
            if(ls<lt){
                return 0;
            }
            
            int[][] memo = new int[ls][lt];
            char[] cs = S.toCharArray();
            char[] ct = T.toCharArray();
            
            memo[0] = new int[lt];
            memo[0][0]= (cs[0]==ct[0])?1:0;
            
            for(int i=1;i<ls;++i){
                int[] mprev = memo[i-1];
                int[] m = memo[i] = new int[lt];
                char s = cs[i];
                for(int j=0;j<lt;++j){
                    char t = ct[j];
                    m[j] = mprev[j];
                    if(s==t){
                        m[j] += ((j==0)?1:mprev[j-1]);
                    }
                }
            }
            return memo[ls-1][lt-1];
        }

    評論

    # re: 子序列計數(shù)  回復  更多評論   

    2013-06-12 23:56 by 初學者:阿古

    7.字符串String str = “ABCDEABCDABC”;定義一個方法query,8.該方法算出該字符串中每一個字符的個數(shù),9.打印格式如:
    A——3
    B——3
    C——3
    D——2
    E——1
    主站蜘蛛池模板: 亚洲成a人片在线观看精品| 情人伊人久久综合亚洲| 亚洲中文字幕无码av永久| 日韩人妻无码精品久久免费一| 中文字幕无码精品亚洲资源网久久 | 九一在线完整视频免费观看| 四虎永久成人免费| 无码 免费 国产在线观看91| 免费一级毛片免费播放| 一级做受视频免费是看美女| 亚洲精品无码av天堂| 国产免费人成视频尤勿视频| 精品亚洲综合在线第一区| 小日子的在线观看免费| 久久亚洲AV无码精品色午夜| 免费福利网站在线观看| 亚洲日本一线产区和二线产区对比| 男人的好看免费观看在线视频| 亚洲欧美成aⅴ人在线观看| 日韩免费视频在线观看| 成人在线免费视频| 久久青青草原亚洲AV无码麻豆| 最近最新高清免费中文字幕| 亚洲午夜在线播放| 免费国产美女爽到喷出水来视频| 亚洲免费一区二区| 亚洲第一永久在线观看| 日韩视频在线免费观看| 亚洲精品偷拍视频免费观看| 亚洲美女自拍视频| 国产免费直播在线观看视频| 大妹子影视剧在线观看全集免费 | 亚洲成AV人片天堂网无码| 精品福利一区二区三区免费视频 | 日韩精品无码区免费专区| 麻豆一区二区三区蜜桃免费| 亚洲av永久无码精品网站| 国拍在线精品视频免费观看 | 日日摸夜夜添夜夜免费视频| 亚洲自偷自偷精品| 国产日韩精品无码区免费专区国产 |