LeetCode困难刷题记录——Regular Expression Matching 正则表达式匹配

1 篇文章 0 订阅
1 篇文章 0 订阅

问题:

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

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

 

分析:

其实这题没什么特殊的思路,很典型的动态规划题,只要不同情况考虑得全面即可

 

代码:

/**
 * 正则表达式匹配
 * Regular Expression Matching
 *
 * @author DongWei
 * @version 2019/6/19
 */
class Solution {
    public boolean isMatch(String s, String p) {
        // 动态规划准备,match[i][j] 表示 s 的 0 到 i-1 位和 p 的 0 到 j-1 位是否可以匹配
        boolean[][] match = new boolean[s.length() + 1][p.length() + 1];
        char[] ss = s.toCharArray();
        char[] ps = p.toCharArray();

        // 初始化,p 开头的 * 可以跳过匹配
        match[0][0] = true;
        int idx = 1;
        while (idx < ps.length && ps[idx] == '*') {
            match[0][idx + 1] = true;
            idx += 2;
        }

        // 动态规划
        for (int i = 0; i < ss.length; i ++) {
            for (int j = 0; j < ps.length; j ++) {
                char a = ss[i];
                char b = ps[j];
                // 如果 pattern 的这一位为'.',无论是什么字符都可以匹配成功
                if (b == '.') {
                    match[i + 1][j + 1] = match[i][j];
                } else if (b == '*') {
                    // 如果 pattern 的这一位为'*'
                    if (a == p.charAt(j - 1) || ps[j - 1] == '.') {
                        // 如果字符串的这一位和 * 前的字符匹配(字符相等或 pattern 前一位是'.'
                        // 考虑两种情况,第一种是与 * 匹配,第二种是跳过 * 匹配
                        // 与 * 匹配,又可以分为两种情况,前面的字符串匹配到了 * 或没有,分别是 match[i][j - 1] 和 match[i][j + 1]
                        // 但是在 p[j] 为 * 的情况下,match[i][j - 1] 为 true 的时候 match[i][j+1] 必然为 true
                        // 因此省略 match[i][j - 1]
                        match[i + 1][j + 1] = match[i][j + 1] | match[i + 1][j - 1];
                    } else {
                        // 如果字符串的这一位和 * 前的字符不匹配,只能跳过 * 的匹配
                        match[i + 1][j + 1] = match[i + 1][j - 1];
                    }
                } else {
                    // 如果 pattern 的这一位为普通字符,根据字符是否相等判断是否匹配
                    if (a == b) {
                        match[i + 1][j + 1] = match[i][j];
                    } else {
                        match[i + 1][j + 1] = false;
                    }
                }
            }
        }

        // 返回匹配结果
        return match[ss.length][ps.length];
    }
}

 

运行速度5ms~10ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值