【刷题记录】10. 正则表达式匹配

简介: 【刷题记录】10. 正则表达式匹配

一、题目描述


来源:力扣(LeetCode)


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


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


示例 1:


输入:s = "aa", p = "a"

输出:false

解释:"a" 无法匹配 "aa" 整个字符串。


示例 2:


输入:s = "aa", p = "a*"

输出:true

解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。

因此,字符串 "aa" 可被视为 'a' 重复了一次。


示例 3:


输入:s = "ab", p = ".*"

输出:true

解释:".*" 表示可匹配零个或多个('*')任意字符('.')。


提示:


  • 1 <= s.length <= 20
  • 1 <= p.length <= 30
  • s 只包含从 a-z 的小写字母。
  • p 只包含从 a-z 的小写字母,以及字符 . 和 *。
    **保证每次出现字符 时,前面都匹配到有效的字符


二、思路分析


这个题目我可以利用动态规划的思想来解决:


  • 首先我们定义dp[i][j] 表示 s 的前 i 个是否能被 p 的前 j 个匹配
  • 如果 p 的第 j 个字符是一个字母
  • 如果 s 的第 i 个字符与 p 的第 j 个字符不相同,那么无法进行匹配,不符合了。
  • 如果前面的都匹配的同时,且  s 的第 i 个字符与 p 的第 j 个字符相同,即 dp[i-1][j-1] = dp[i,j] && s[i]=p[j]
  • 如果 p 的第 j 个字符是 *, 那么我们就是对 前面一个字符p[j-1]就行任意次数的匹配
  • 0 次就是 dp[i][j] == dp[i][j-2]
  • 1 次就是 dp[i][j] == dp[i−1][j−2] && s[i] == p[j-1]
  • 2 次就是 dp[i][j] == dp[i−2][j−2] && s[i-1]s[i] == p[j-1]
  • ....
    总结就是

网络异常,图片无法展示
|

  • 如果  p[j]'.':匹配的条件是前面的字符匹配, s 中的第 i 个字符可以是任意字符。即 dp[i,j] = dp[i - 1, j - 1] && p[j] == '.'
  • 动态规划的边界条件为
    网络异常,图片无法展示
    |
    ,即两个空字符串是可以匹配的。最终的答案即为
    网络异常,图片无法展示
    |
    ,其中 mn 分别是字符串 sp 的长度


三、代码实现

class Solution {
    public boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();
        //dp[i][j] s 中的 1~i 字符 和 p 中的 1~j 字符 是否匹配
        boolean[][] dp = new boolean[m +1][n +1];
        dp[0][0] =true;
for (int i =0; i <= m; ++i) {
for (int j =1; j <= n; ++j) {
if (p.charAt(j -1) =='*') {
                    dp[i][j] = dp[i][j -2];
if (matches(s, p, i, j -1)) {
                        dp[i][j] = dp[i][j] || dp[i -1][j];
                    }
                } else {
if (matches(s, p, i, j)) {
                        dp[i][j] = dp[i -1][j -1];
                    }
                }
            }
        }
        return dp[m][n];
    }
    public boolean matches(String s, String p, int i, int j) {
if (i ==0) {
            return false;
        }
if (p.charAt(j -1) =='.') {
            return true;
        }
        return s.charAt(i -1) == p.charAt(j -1);
    }
 }


复杂度分析


复杂度分析


  • 时间复杂度:
    网络异常,图片无法展示
    |
    ,其中 mn 分别是字符串 sp 的长度,每个状态在进行转移时的时间复杂度为
    网络异常,图片无法展示
    |
  • 空间复杂度:
    网络异常,图片无法展示
    |
    ,存储所有状态使用的空间。


运行结果


网络异常,图片无法展示
|


总结


这道题的重点是 动态规划 的运用


而动态规划的解题核心主要分为两步:


  1. 第一步:状态的定义
  2. 第二步:状态转移方程的定义


状态表示的是我们在求解问题之中,对问题的分析和转化


运用动态规划我们将一个大问题转化成几个小问题,求解小问题,然后推出大问题的解

目录
相关文章
|
7月前
|
JavaScript 前端开发 Java
|
6月前
|
机器学习/深度学习 JavaScript 前端开发
技术心得记录:正则表达式(c#)
技术心得记录:正则表达式(c#)
27 0
|
存储 Cloud Native Go
【刷题日记】1455. 检查单词是否为句中其他单词的前缀
【刷题日记】1455. 检查单词是否为句中其他单词的前缀
114 1
|
7月前
|
Java
每日一刷《剑指offer》字符串篇之正则表达式匹配
每日一刷《剑指offer》字符串篇之正则表达式匹配
74 0
每日一刷《剑指offer》字符串篇之正则表达式匹配
|
7月前
|
算法 C#
Leetcode算法系列| 10. 正则表达式匹配
Leetcode算法系列| 10. 正则表达式匹配
|
算法 安全 Swift
LeetCode - #44 通配符匹配
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
LeetCode - #44 通配符匹配
|
算法 C语言 数据安全/隐私保护
【C++技能树】快速文本匹配 --正则表达式介绍与C++正则表达式使用
假设要判断一个QQ号是否有效,他必须满足以下三个规则
127 0
|
JavaScript
剑指offer 18. 正则表达式匹配
剑指offer 18. 正则表达式匹配
59 0
|
程序员
学好正则表达式,啥难匹配的内容都给我匹配上
学好正则表达式,啥难匹配的内容都给我匹配上
|
算法 前端开发 程序员
实现正则表达式匹配算法
实现正则表达式匹配算法
实现正则表达式匹配算法