題目鏈接:模式匹配
題目描述:
你有兩個字符串,即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;
}
}