<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 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    交叉字符串

    Posted on 2013-05-10 20:47 小明 閱讀(3239) 評論(4)  編輯  收藏 所屬分類: 數據結構和算法
    問題給定字符串s1,s2,s3,判斷s3是否可以由s1和s2交叉組成得到。

    例如:

    s1 = "aabcc",
    s2 = "dbbca",

    When s3 = "aadbbcbcac", return true.
    When s3 = "aadbbbaccc", return false.


    解法一:(遞歸)

    一個簡單的想法,是遍歷s3的每個字符,這個字符必須等于s1和s2的某個字符。如果都不相等,則返回false
    我們使用3個變量i,j,k分別記錄當前s1,s2,s3的字符位置。
    如果s3[k] = s1[i], i向后移動一位。如果s3[k]=s2[j],j向后移動一位。
    這個題目主要難在如果s1和s2的字符出現重復的時候,就有兩種情況,i,j都可以向后一位。
    下面的算法在這種情況使用了遞歸,很簡單的做法。但是效率非常差,是指數復雜度的。

    public class Solution {
        public boolean isInterleave(String s1, String s2, String s3) {
            int l1 = s1.length();
            int l2 = s2.length();
            int l3 = s3.length();
            
            if(l1+l2!=l3){
                return false;
            }
            
            char[] c1 = s1.toCharArray();
            char[] c2 = s2.toCharArray();
            char[] c3 = s3.toCharArray();
            
            int i=0,j=0;
            for(int k=0;k<l3;++k){
                char c = c3[k];
                boolean m1 = i<l1 && c==c1[i];
                boolean m2 = j<l2 && c==c2[j];
                if(!m1 && !m2){
                    return false;
                }
                else if(m1 && m2){
                    String news3 =  s3.substring(k+1);
                    return isInterleave(s1.substring(i+1),s2.substring(j),news3)
                                    || isInterleave(s1.substring(i),s2.substring(j+1),news3);
                }
                else if(m1){
                    ++i;
                }
                else{
                    ++j;
                }
            }
            
            return true;        
        }
    }


    解法二:(動態規劃)
    為了減少重復計算,就要使用動態規劃來記錄中間結果。

    這里我使用了一個二維數組result[i][j]來表示s1的前i個字符和s2的前j個字符是否能和s3的前i+j個字符匹配。

    狀態轉移方程如下:
    result[i,j] = (result[i-1,j] && s1[i] = s3[i+j])  || (result[i,j-1] && s2[j] = s3[i+j]);
    其中0≤i≤len(s1) ,0≤j≤len(s2)

    這樣算法復雜度就會下降到O(l1*l2)
    public class Solution {
       
    public boolean isInterleave(String s1, String s2, String s3) {
            int l1 = s1.length();
            int l2 = s2.length();
            int l3 = s3.length();
           
            if(l1+l2!=l3){
                return false;
            }
            
            char[] c1 = s1.toCharArray();
            char[] c2 = s2.toCharArray();
            char[] c3 = s3.toCharArray();
            
            boolean[][] result = new boolean[l1+1][l2+1];
            result[0][0] = true;
            
            for(int i=0;i<l1;++i){
                if(c1[i]==c3[i]){
                    result[i+1][0] = true;
                }
                else{
                    break;
                }
            }
            
            for(int j=0;j<l2;++j){
                if(c2[j]==c3[j]){
                    result[0][j+1] = true;
                }
                else{
                    break;
                }
            }
            
            
            for(int i=1;i<=l1;++i){
                char ci = c1[i-1];
                for(int j=1;j<=l2;++j){
                    char cj = c2[j-1];
                    char ck = c3[i+j-1];
                       result[i][j] = (result[i][j-1] && cj==ck) || (result[i-1][j] && ci==ck);
                }
            }
            
            return result[l1][l2];
       }
    }

    評論

    # re: 交叉字符串  回復  更多評論   

    2013-05-11 10:19 by 開發吧
    今天正在搞這個問題,謝謝啦!

    # re: 交叉字符串  回復  更多評論   

    2013-05-12 21:09 by tb
    算法 對我有點啟發 謝謝

    # re: 交叉字符串  回復  更多評論   

    2013-05-13 11:23 by javanewer
    boolean[][] result = new boolean[l1+1][l2+1];
    這一句什么作用?

    # re: 交叉字符串[未登錄]  回復  更多評論   

    2013-05-15 18:57 by wang
    交叉字符串是用來干嘛的
    主站蜘蛛池模板: 亚洲色成人网一二三区| 亚洲午夜国产精品无码老牛影视| 久久夜色精品国产噜噜亚洲AV| 日韩a级无码免费视频| 亚洲精品无码久久久久去q| 成人黄色免费网址| 亚洲人成在线观看| 亚洲一级毛片免费观看| 亚洲网红精品大秀在线观看| 日韩精品极品视频在线观看免费| 亚洲狠狠综合久久| 久九九精品免费视频| 久久亚洲最大成人网4438| 啦啦啦在线免费视频| 精品国产日韩亚洲一区91| 亚洲毛片不卡av在线播放一区| 一级毛片免费在线观看网站| 中文亚洲AV片不卡在线观看| 国产成人精品无码免费看| 亚洲国产午夜电影在线入口| 成人av免费电影| 日本在线观看免费高清| 亚洲VA中文字幕无码毛片 | xxxxx做受大片在线观看免费| 亚洲男人第一无码aⅴ网站| AAA日本高清在线播放免费观看| 久久亚洲精品无码AV红樱桃| 成人午夜18免费看| 一级毛片免费播放视频| 亚洲视频在线免费播放| 精品国产免费观看| 国产免费网站看v片在线| 亚洲最大成人网色香蕉| 亚洲成?v人片天堂网无码| 国产99视频精品免费专区| 亚洲国产综合精品中文第一| 国产成人亚洲精品影院| 免费观看无遮挡www的小视频| 337P日本欧洲亚洲大胆精品 | 免费福利视频导航| 青草久久精品亚洲综合专区|