剑指 Offer 19. 正则表达式匹配

class Solution {
    public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();
        boolean[][] dp = new boolean[n+1][m+1];
        dp[0][0] = true;//空串和空正则匹配
        for(int i = 1;i <= n;i++){
            dp[i][0] = false;//非空串和正则一定不匹配
        }

        //非空正则和(空串和非空串匹配)
        for(int i = 0;i <= n;i++){
            for(int j = 1;j <= m;j++){
                if(m==1){
                    dp[i][j] = false;//特殊处理,如果第一个字符为空,正则第一个为*,必失败
                }else if(i==0){
                    dp[i][j] = false;//特殊处理
                }
                if(p.charAt(j-1)=='*'){
                    dp[i][j] = dp[i][j-2];
                    if(i!=0 && ((p.charAt(j-2)==s.charAt(i-1))||p.charAt(j-2)=='.')){
                        dp[i][j] = dp[i][j] || dp[i-1][j];//如果正则最后一个字符匹配成功,就将字串减
                    }else{
                        dp[i][j] = dp[i][j-2];//如果正则最后一个字符匹配失败,正则减2
                    }
                }else if(i!=0 && p.charAt(j-1)=='.'){
                    dp[i][j] = dp[i-1][j-1];//如果是.一定匹配成功,同时前退1
                }else if(i!=0 && p.charAt(j-1)==s.charAt(i-1)){
                    dp[i][j] = dp[i-1][j-1];//如果是匹配的字符就同时前退1
                }
            }
        }
        return dp[n][m];
    }
}

需要注意的点,遇到*号开始倒推时,应该先假设没有匹配成功,再逐步退回字符来判断是否成功。最重要的是先假设没有匹配成功,因为如果先退回字符有可能退的超过指定字符,所以先假设没有匹配成功,这样就可以获取没有超退回字符状态下能否匹配成功,再将没有回退的装态和超出回退的状态取余,就可以保证不会超出回退。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值