LeetCode 10:正则表达式匹配

7. LeetCode 10:正则表达式匹配

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

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

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

解析:

方法一:递归解决

只考虑s,p的第一个字符:

  • 若p为空,只有s也为空时匹配;

  • 若第一个字符匹配,

    • 若p的第二个字符不为’*’,递归调用isMath(s.substring(1),p.substring(1))。
    • 若p的第二个字符为’*’,考虑匹配的字符是否存在多个或根本不存在,isMatch(s,p.substring(2))或isMatch(s.substring(1),p);
  • 若第一个字符不匹配,

    • 若p的第二个字符不为’*’,false
    • 若p的第二个字符为’*’,p(0)不在s中,isMatch(s,p.substring(2))

代码(转化为数组速度更快):

	public boolean isMatch(String s, String p) {
        if(p.isEmpty()){return s.isEmpty();}
        return isMatch(s.toCharArray(),0,p.toCharArray(),0);
        
    }

    public boolean isMatch(char[] s, int i,char[] p,int j){
        if(j>=p.length){return i>=s.length;}

        if(i<s.length&&(p[j]==s[i]||p[j]=='.')){
            if(j+1<p.length&&p[j+1]=='*'){
                return isMatch(s,i,p,j+2)||isMatch(s,i+1,p,j);
            }else{
                return isMatch(s,i+1,p,j+1);
            }
        }else{
            if(j+1<p.length&&p[j+1]=='*'){
                return isMatch(s,i,p,j+2);
            }else{
                return false;
            }
        }
    }
方法二:动态规划

考虑到第一种解法中大量使用i,j后面的结果,考虑动态规划

从后往前找,可以用填表的方法找思路

class Solution {
    public boolean isMatch(String text, String pattern) {
        boolean[][] dp = new boolean[text.length() + 1][pattern.length() + 1];
        dp[text.length()][pattern.length()] = true;

        for (int i = text.length(); i >= 0; i--){
            for (int j = pattern.length() - 1; j >= 0; j--){
                boolean first_match = (i < text.length() &&
                                       (pattern.charAt(j) == text.charAt(i) ||
                                        pattern.charAt(j) == '.'));
                if (j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){
                    dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
                } else {
                    dp[i][j] = first_match && dp[i+1][j+1];
                }
            }
        }
        return dp[0][0];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值