10. 正则表达式匹配

题目

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。

‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

在这里插入图片描述

代码

class Solution {
    HashMap<String,Boolean> memo;
    public boolean isMatch(String s, String p) {
        memo =new HashMap<>();
        // 指针 i,j 从索引 0 开始移动
      return   dp(s,0,p,0);
    }

    boolean dp(String s,int i,String p, int j){//i,j之后能否匹配
        int m=s.length(),n=p.length();
//        base case
        if (j==n) return i==m;
        if (i==m){
            if ((n-j)%2==1) return false;//之后p要以b*c*这种形式才行,如果能匹配空串,一定是字符和 * 成对儿出现
            // 检查是否为 x*y*z* 这种形式
            for (; j<n; j+=2) {
                if (p.charAt(j+1)!='*') return false;
            }
            return true;
        }
        // 记录状态 (i, j),消除重叠子问题
        String k = i+","+j ;
        if (memo.containsKey(k)) return memo.get(k);

        boolean res =false;

        if (s.charAt(i)==p.charAt(j)||p.charAt(j)=='.'){
            // 匹配
            if (j<n-1&&p.charAt(j+1)=='*'){//若果后面跟着*,要作其他打算
                // 1.1 通配符匹配 0 次或多次
                res= dp(s,i,p,j+2)||dp(s,i+1,p,j);//前面是0次,后面是1次以上

            }else {
                // 1.2 常规匹配 1 次
                res= dp(s,i+1,p,j+1);
            }
        }else {
//            不匹配的情况
            if (j<n-1 && p.charAt(j+1)=='*'){//若后面有*能续命
                // 2.1 通配符匹配 0 次
                res= dp(s,i,p,j+2);
            }else {//寄了
                res= false;
            }
        }
        //加入备忘录
        memo.put(k,res);
        return res;
    }
}

要点

  • 由于.和* 的特殊匹配方式,所以需要逐个分析,并利用动态规划进行遍历
  • 在判断是否匹配结束的时候,也需要进行分析,不能简单的判断是否结束
  • 使用哈希表来消除重复子问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值