<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 小明 閱讀(3232) 評論(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
    交叉字符串是用來干嘛的
    主站蜘蛛池模板: 亚洲一区二区在线免费观看| 国产亚洲精AA在线观看SEE| 亚洲黄色网站视频| a级毛片免费完整视频| 亚洲中文字幕在线乱码| 精品久久久久久无码免费| a级亚洲片精品久久久久久久| 日韩在线观看免费完整版视频| 亚洲人成无码久久电影网站| 国产99久久久国产精免费| 亚洲VA成无码人在线观看天堂| 日本免费人成网ww555在线| 67pao强力打造67194在线午夜亚洲| 久久久久久夜精品精品免费啦| 91大神亚洲影视在线| 中文字幕人成无码免费视频| 亚洲精品成a人在线观看夫| 国产成人免费永久播放视频平台| 女人裸身j部免费视频无遮挡| 久久亚洲中文字幕精品一区四| 中国一级毛片免费看视频| 亚洲人成电影福利在线播放| 真人做人试看60分钟免费视频 | 最近中文字幕无免费视频| 亚洲 日韩经典 中文字幕| 国产日产成人免费视频在线观看| 一级毛片在线完整免费观看| 亚洲2022国产成人精品无码区 | 亚洲A∨精品一区二区三区| 永久免费A∨片在线观看| 亚洲熟妇色自偷自拍另类| 女人与禽交视频免费看| 一个人看的免费视频www在线高清动漫| 久久精品国产精品亚洲精品| 麻豆一区二区免费播放网站| 免费无码AV一区二区| 亚洲高清视频免费| 亚洲日韩在线观看| 天天影视色香欲综合免费| 日韩毛片免费一二三| 亚洲精品自拍视频|