题目链接:模式匹配
题目描述:
你有两个字符串,即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;
}
}