博客
关于我
LeetCode.10 Regular Expression Matching (正则表达式匹配)
阅读量:707 次
发布时间:2019-03-17

本文共 1904 字,大约阅读时间需要 6 分钟。

为了实现支持 '.' 和 '*' 的正则表达式匹配,我们可以利用动态规划来在 O(n) 的时间复杂度内完成任务,其中 n 是输入字符串的长度。动态规划法能有效处理边界情况,并确保整个输入被完全匹配。

解题思路

  • 初始化数组:创建一个大小为 n+1 的布尔数组 dp,其中 dp[i] 表示前 i 个字符是否能够与模式的前 i 个字符完全匹配。初始化 dp[n]true,表示当输入完全被匹配时,状态为 true

  • 从后到前处理模式字符:遍历模式字符串的每个字符,从最后一个字符到第一个字符。根据当前字符的类型,更新 dp 数组:

    • 遇到星号 '*':将 dp[i-1] 的状态与当前状态合并,确保匹配尽可能多的字符。
    • 遇到普通字符:检查输入字符串的对应位置是否与模式字符匹配(包括 '.' 代表的任意字符),并更新状态。
  • 处理边界情况:确保在处理每个字符之前和之后,状态转移逻辑正确,避免遗漏边界条件。

  • 动态规划状态转移

    • 全匹配状态:当 dp[j]dp[j+1] 都为 true 时,表示当前匹配状态有效。
    • 星号处理:星号允许匹配任意数量,包括零个或多个,因此只要后续状态有效,当前状态就可以设置为 true
    • 具体字符匹配:检查当前字符是否等于输入字符串的对应字符或是 '.'。

    代码实现

    public class Solution {    public boolean isMatch(String s, String p) {        int n = s.length();        int m = p.length();        // 处理特殊情况:空模式或空字符串不匹配        if (m == 0 || n == 0) {            return m == n && p.isEmpty() && s.isEmpty();        }        // 创建动态规划数组        boolean[] dp = new boolean[n + 1];        dp[n] = true; // 初始化,全匹配的情况        // 从后向前处理每个字符        for (int j = m - 1; j >= 0; j--) {            // 当前字符来自模式            char c = p.charAt(j);            // 当前处理的是第j个字符,要影响到dp[j+1]            if (c == '*') {                // 星号的情况,我们可以把dp[j]设为dp[j] || dp[j+1]                dp[j] = dp[j] || dp[j + 1];            } else {                // 非星号的情况,只能从前往后检查                if (j + 1 > n) {                    // 当前处理到字符时,已经超出字符串长度                    dp[j] = dp[j + 1];                } else {                    char sc = s.charAt(j);                    dp[j] = dp[j + 1] && ((sc == c) || (sc == '.');                    // 注意这里的逻辑是当前字符要和模式字符或.匹配                }            }        }        // 处理最后的特殊情况,比如:        // 当j =0时,要看是否整个字符串都被匹配        // 特别是,当p不是以星号结尾的时候,可能有的边界情况        return dp[0];    }}

    代码解释

    • 初始化处理:创建 dp 数组,并将最后一个状态设置为 true,表示输入已完全匹配。
    • 倒序遍历模式字符串:从模式的最后一个字符开始处理,检查每个字符的类型,并根据类型更新 dp 数组。
    • 处理星号字符:如果当前字符是星号,状态转移较为复杂,需要综合前后状态。
    • 处理普通字符:检查当前字符是否能与输入字符串中的对应字符匹配,更新状态为 truefalse

    这种方法确保了在每个步骤中正确处理所有可能的匹配情况,从而实现完整的正则表达式匹配。

    转载地址:http://vdjez.baihongyu.com/

    你可能感兴趣的文章
    mysql 使用sql文件恢复数据库
    查看>>
    mysql 修改默认字符集为utf8
    查看>>
    Mysql 共享锁
    查看>>
    MySQL 内核深度优化
    查看>>
    mysql 内连接、自然连接、外连接的区别
    查看>>
    mysql 写入慢优化
    查看>>
    mysql 分组统计SQL语句
    查看>>
    Mysql 分页
    查看>>
    Mysql 分页语句 Limit原理
    查看>>
    MySQL 创建新用户及授予权限的完整流程
    查看>>
    mysql 创建表,不能包含关键字values 以及 表id自增问题
    查看>>
    mysql 删除日志文件详解
    查看>>
    mysql 判断表字段是否存在,然后修改
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>
    mySQL 多个表求多个count
    查看>>
    mysql 多字段删除重复数据,保留最小id数据
    查看>>
    MySQL 多表联合查询:UNION 和 JOIN 分析
    查看>>
    MySQL 大数据量快速插入方法和语句优化
    查看>>