正则表达式匹配

题目:力扣

解题思路:

做这道题运用的递归的思路。

我们从左到右进行匹配,若当前匹配成功地话,则最后的结果取决于后面是否也能匹配成功。若当前匹配失败的话,则直接返回失败。

我们从左到右对s的字符一个一个进行匹配。

首先,考虑特殊情形:

s.length()p.length()结果
00true
0!0不确定
!00false
!0!0

                 不确定

 可以看出,当p为空字符串的时候,结果取决于s是否是空字符串。这也是为什么一上来就判断p是不是空串。

  • 当p为空串时,结果由s决定。
  • 当p不为空串时,再执行下面的代码

我们接下来讨论当p不是空串的时候。

对s的字符挨个进行判断,对于s的第一个字符(要满足s不为空串),p的第一个字符是什么的时候才能正确匹配呢?我们能够确定s的第一个字符一定是字母,而p的第一个字符一定是字母或'.'

  1. 当p的第一个字符是字母时,且等于s的第一个字母时,一定能匹配。
  2. 当p的第一个字符是'.'时,因为'.'能够代表任意值,因此一定能匹配。

我们能够得到first的值了。

当first为true时,能够确定满足上面两条中的其中之一。

当前字符满足匹配了,我们需要考虑s下一个字符的匹配了。现在需要用到递归了。

  • 满足条件2的情况比较简单,直接返回isMatch(s(1...len), p(1...len))
  • 满足条件1时,也需要分情况讨论了:
  1. 第二个字符是*时,因为*可以代表多个前一个字符,所以需要保留第一个字符,以达到这种效果,返回isMatch(s(1...len), p)
  2. 第二个字符不是*时,直接返回isMatch(s(1...len), p(1...len))

当first为false的时候,能够确定的是s为空串,或者是p的第一个字符其实就是字母和s的不相等。

  • 当p的第二个字符是*的时候,虽然第一个字母和s不匹配,但是因为a*可以代表零个字母,可以忽略*和*号前面的字母,返回isMatch(s, p(2...len))
  • 当p的第二个字符不是*的时候,无论怎样,第一个字符都不能去掉也无法匹配,因此可以直接返回false。

 

class Solution {
    public boolean isMatch(String s, String p) {
        if(p.isEmpty()){
            return s.isEmpty();
        }
        boolean first = !s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.');
        if(first){
            if(p.length()>=2 && p.charAt(1) == '*')
                return isMatch(s.substring(1),p);
            else
                return isMatch(s.substring(1), p.substring(1));
        }
        else{
            return p.length()>=2 && isMatch(s, p.substring(2));
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值