leetcode面試題模式匹配

題目鏈接:模式匹配
題目描述:
你有兩個字符串,即pattern和value。 pattern字符串由字母"a"和"b"組成,用於描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a",“go"是"b”),該字符串也匹配像"a"、"ab"和"b"這樣的模式。但需注意"a"和"b"不能同時表示相同的字符串。編寫一個方法判斷value字符串是否匹配pattern字符串。

示例 1:

輸入: pattern = “abba”, value = “dogcatcatdog”
輸出: true
示例 2:

輸入: pattern = “abba”, value = “dogcatcatfish”
輸出: false
示例 3:

輸入: pattern = “aaaa”, value = “dogcatcatdog”
輸出: false
示例 4:

輸入: pattern = “abba”, value = “dogdogdogdog”
輸出: true
解釋: “a”=“dogdog”,b="",反之也符合規則
提示:

0 <= len(pattern) <= 1000
0 <= len(value) <= 1000
你可以假設pattern只包含字母"a"和"b",value僅包含小寫字母。

題目分析:這道題,我一開始真的一點思路都沒得,哭了哭了,太菜了,確定是medium難度的題嗎!總之,這是一個比較複雜的模擬題,我們先從邊界情況開始考慮:
如果pattern爲空,那麼只有value爲空才能滿足匹配
如果value爲空,此時pattern爲空或者只有一個字母(a/b)時,此時可以將這個字母設置爲空,來達到匹配的目的
如果pattern與value都不爲空,此時就是我們的正文了。
直接去枚舉各自字符串的話更復雜了,我們可以嘗試通過枚舉字串(a/b)長度來簡化處理過程。由題目描述可知,除了字串本身還有個數來決定是否匹配,所以這兩個因素都要考慮到,而個數是確定的(直接對pattern計算即可),那麼只需要枚舉長度就可以了。同時,確定了a長度之後,b的長度也就確定了。假設,確定了a的長度,同時計算出b的長度,接下來對value進行遍歷,對pattern匹配到a/b時,對value對應的字串進行判斷,value的字串部分怎麼控制呢?通過一個指針來截取即可。
只要不相等即爲不匹配。所以,只要我們能找到一個len(a,b)解即可。還有一個點,a與b是不能相同的,這個也要進行判斷。這題真的細節挺多的,看代碼吧

class Solution {
    public boolean patternMatching(String pattern, String value) {
        int cntA = 0,cntB = 0;
        //統計a,b個數
        for (char c : pattern.toCharArray()) {
            cntA += c=='a'?1:0;
            cntB += c=='b'?1:0;
        }
        //對稱性,a/b都是相同的,以個數大的去計算,符合下面算法的通用性
        //交換
        if(cntA<cntB){
            int te = cntA;
            cntA = cntB;
            cntB = te;
            char[] change = new char[pattern.length()];
            int i = 0;
            for (char c : pattern.toCharArray()) {
                change[i++]= c=='a'?'b':'a';
            }
            pattern = new String(change);
        }
        //邊界情況
        if(value.length()==0) return cntB == 0;
        if(pattern.length()==0) return false;
        //都不爲空
        for(int lenA = 0;lenA*cntA<=value.length();lenA++){
            int rest = value.length()-cntA*lenA;
            if((cntB==0&&rest==0)||(cntB!=0&&rest%cntB==0)){
                int lenB = (cntB==0?0:rest/cntB);
                boolean isOK = true;
                String strA = "",strB = "";
                int pos = 0;
                for (char c : pattern.toCharArray()) {
                    if(c == 'a'){
                       String sub = value.substring(pos,pos+lenA);
                       if(strA.length()==0){//第一次匹配
                           strA = sub;
                       }else{
                           if(!strA.equals(sub)) { //再次遇到就判斷
                               isOK = false;
                               break;
                         }
                       }
                       pos += lenA;
                    }else{
                        String sub = value.substring(pos,pos+lenB);
                        if(strB.length()==0){//同上
                            strB = sub;
                        }else{
                            if(!strB.equals(sub)) { 
                                isOK = false;
                                break;
                          }
                        }
                        pos += lenB;
                    }
                } 
                //a,b代表的字串不能相同
                if(isOK&&!(strA.equals(strB))) return true; 
            }
           
        }
        return false;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章