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;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值