leetcode 面试题 16.18.模式匹配

原题

面试题 16.18.模式匹配
在这里插入图片描述

题解

方法一

这个方法类似于遍历所有的a和b可能代表的字符串类型,但又不完全是,因为在这个方法中作了一些简化和转化问题的考虑。
由于只用考虑两种字符串的代表(也就是ab),那么我们可以假设为a代表的字符串长度为la,b代表的为lb,而pattern里面a和b分别有na和nb个,很显然我们得到na*la+nb*lb=value.length,对于给定pattern,na和nb确定,只需要先求出这个方程的la和lb整数解就好。假设从la取值是0开始直到la*lb不大于value.length的最大值,这样就响应求出可以是整数的lb。之后再根据pattern内第一个字母,假设是a,截取value的前la位即为此循环中a代表的字符串sa,在进而找到b可能代表的字符串sb,此时我们根据pattern把它以sa和sb为组成的字符串拼出并且和value比较,相同的话就直接返回真了,如果不同,继续寻找另一组la(进而sa)和lb(进而sb);字符串patt首位为b道理想同。
不过一些陷阱和特殊情况需要考虑在内。比如字符串pattern内只有一种字母,例如只有a(只有b的道理也一样),那么就可以用value.length/(a的个数),得到a代表的sa的长度la,截取value前la字符为sa,sa连续la次,和源value比较;l为0时,pattern里面ab不能同时存在;或者pattern直接为空,l不空,那就是假。哦对sa!=sb!!
本思路java代码示例:

/*
 *@v7fgg
 *执行用时:3 ms, 在所有 Java 提交中击败了35.05%的用户
 *内存消耗:39.8 MB, 在所有 Java 提交中击败了100.00%的用户
 *2020年6月22日 10:50
 */
class Solution {
    public boolean patternMatching(String pattern, String value) {
        int l=value.length();
        //首先空pattern空value是匹配的
        if(l==0&&pattern.length()==0){return true;}
        int na=0;//字符a的个数
        for(int i=0;i<pattern.length();i++){
            na+=pattern.charAt(i)=='a'?1:0;
        }
        int nb=pattern.length()-na;//字符b的个数
        //pattern有a有b,但是空value不可以
        if(l==0&&na>0&&nb>0){return false;}
        //下面考虑pattern不为空
        if(pattern.length()>0){
            //ab都有
            if(na>0&&nb>0){
                //求方程na*la+nb*lb=l的自然数解
                int la=0;//a代表的字符串可能的长度
                while(la*na<=l){
                    int lb=(l-la*na)/nb;//b代表的字符可能的串长度
                    if(na*la+nb*lb==l){
                        String sa="";//a可能代表的字符串
                        String sb="";//b可能代表的字符串
                        if(pattern.charAt(0)=='a'){
                            sa=value.substring(0,la);
                            for(int i=1;i<pattern.length();i++){
                                if(pattern.charAt(i)=='b'){
                                    sb=value.substring(i*la,i*la+lb);
                                    break;
                                }
                            }
                        }
                        if(pattern.charAt(0)=='b'){
                            sb=value.substring(0,lb);
                            for(int i=0;i<pattern.length();i++){
                                if(pattern.charAt(i)=='a'){
                                    sa=value.substring(i*lb,i*lb+la);
                                    break;
                                }
                            }
                        }
                        if(!sa.equals(sb)){
                            //ab代表的字符串不能一样
                            String v="";
                            for(int i=0;i<pattern.length();i++){
                            v+=pattern.charAt(i)=='a'?sa:sb;
                            }
                            if(v.equals(value)){return true;}
                        }                                   
                    }
                    la++;
                }
            }
            //只有b
            else if(na==0){
                String sb=value.substring(0,value.length()/nb);
                String v="";
                for(int i=0;i<nb;i++){
                    v+=sb;
                }
                return v.equals(value);
            }
            //只有a
            else{
                String sa=value.substring(0,value.length()/na);
                String v="";
                for(int i=0;i<na;i++){
                    v+=sa;
                }
                return v.equals(value);
            }
        }        
        return false;        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可爱抱抱呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值