LeetCode 难题解析 —— 正则表达式匹配 (动态规划)

文章介绍了如何使用动态规划算法处理正则表达式匹配问题,通过构建二维布尔数组,详细分析了不同字符(包括普通字符、点号和星号)在匹配过程中的逻辑,以及如何处理边界情况和空串空正则表达式的匹配。
摘要由CSDN通过智能技术生成

10. 正则表达式匹配

思路解析

这道题虽然看起来不难理解,但却存在多种可能,当然这种可能的数量是有限的,且其规律对于每一次判别都使用,所以自然而然就想到用 动态规划 的方法啦

接下来逐步分析可能的情况:

(s1 为 字符串 的字符数组(长度m),s2 为匹配规律的字符数组(长度n)

由于需要存储每次匹配是否成功的结果,所以需构造一个二维布尔数组,存放对应是否匹配成功

s2 的 每一个匹配字符有三种情况:正常字符、'.' 、'*', 所以可以以此分类

1. 如果s2[n-1] 是正常字符(不是'.' 或 ‘*’) , 则如果 s1[m-1] = s2[n-1], 这时如果前面都匹配成功,则该次也匹配成功,即取决于 s1[0...m-2] 和 s2[0...n-2]是否匹配,否则不能匹配。

2. 如果s2[n-1] 是 '.' 即可满足任意字符,则 s1[m-1] 一定和 '.' 匹配, 这时如果前面匹配成功,即

s1[0...m-2] 和 s2[0...n-2] 都匹配,则该次匹配成功。

3. 如果 s2[n-1] 是 '*' ,则s2[n-2]='x' 可以重复0次或多次,这时s2[n-2]和s2[n-1]为一个整体X,这时会出现两种情况,即s1[m-1] 是 0个字符'x',还是多个'x'中的最后一个

        i. 如果s1[m-1]是0个字符'x', 则s1[m-1]与s2的匹配规则整体X无关,这时只需看s1[0...m-1]      和  s2[0...n-3]是否匹配即可。

        ii. 如果s1[m-1]是多个'x'的最后一个, 则这时候s1[m-1]必须为'x' 或者 s2[n-2] 为’.' 任意字符, 满足该条件后能否匹配则看 s1[0...m-2] 和 s2[0....n-1] 是否匹配。

初始条件和边界情况:空串和空正则表达式匹配:f[0][0] = TRUE

代码详解

话不多说,上代码

class Solution {
    // 动态规划
    public boolean isMatch(String s, String p) {
        char[] s1 = s.toCharArray();
        char[] s2 = p.toCharArray();
        int m = s1.length;
        int n = s2.length;
        boolean[][] f = new boolean[m+1][n+1];
        for(int i = 0; i <= m; i++) {
            // 边界情况:空串和空正则表达式匹配
            f[i][0] = (i==0);
            for(int j = 1; j <= n; j++) {
                f[i][j] = false;
                // 不为'*'的情况: 则当s2[j-1]为任意字符'.' 或者s2[j-1]==s1[i-1]满足
                if(s2[j-1] != '*') {
                    if(i > 0 && (s2[j-1]=='.' || s2[j-1]==s1[i-1])){
                         // 按位或,若 f[i-1][j-1]为true,则f[i][j]为true
                        f[i][j] |= f[i-1][j-1];
                    }
                } else {
                    // 为s2[j-1]'*'的情况: 
                    // 如果s1[i-1]为0个匹配字符, 那么f[i][j] 是否为true取决与 f[i][j-2], 即s1第i-1和s2第j-3比较
                    if(j - 2 >= 0) {
                        f[i][j] |= f[i][j-2];
                    }
                    // s2[j-2]=='.' 或者 s1[i-1]==s2[j-2] 
                    // 则 那么f[i][j] 是否为true取决与 f[i-1][j], 此时i必满足,所以看i-1
                    if(i>0 && j -2 >= 0 && (s2[j-2]=='.' || s1[i-1]==s2[j-2])){
                        f[i][j] |= f[i-1][j];
                    }
                }
            }
        }
        return f[m][n];
    }
}

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值