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

步骤 1:问题性质分析

输入输出条件:
  • 输入
    • 字符串 s:需要匹配的目标字符串,长度为 m
    • 字符串 p:表示匹配模式,长度为 n,其中包含两种特殊字符:
      • .:匹配任意单个字符。
      • *:匹配零个或多个前面的那个字符。
  • 输出
    • 返回 truefalse,表示 p 是否可以完整匹配字符串 s
问题特性:
  1. 匹配必须涵盖整个字符串 s,不能是部分匹配。
  2. 模式中的 . 可以匹配任意单个字符,* 可以匹配零个或多个前面的字符。
  3. 边界情况:
    • sp 为空字符串时,需要特别处理。
    • 如果 p 中存在 *,需要确定其前置字符能否匹配到 s 中的对应字符。
潜在边界条件:
  • s 为空且 p 为空,返回 true
  • s 不为空而 p 为空,返回 false
  • 处理 * 前置字符为 . 或非 . 的不同情况。

步骤 2:解题步骤与算法设计

对于此题,最佳的解决思路是采用 动态规划 方法。动态规划可以有效处理子问题的重叠,避免重复计算,并逐步构建从简单到复杂的匹配结果。

动态规划的核心思想:
  1. 状态定义:定义一个布尔二维数组 dp[i][j],表示 s 的前 i 个字符和 p 的前 j 个字符是否匹配。
  2. 状态转移方程
    • 如果 p[j-1] 是普通字符或是 .,则:
      • dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1] || p[j-1] == '.')
    • 如果 p[j-1]*,它可以匹配零个或多个前面的字符,则需要考虑两种情况:
      • 匹配零个前面的字符:dp[i][j] = dp[i][j-2]
      • 匹配一个或多个前面的字符:dp[i][j] = dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.')
  3. 初始化
    • dp[0][0] = true,表示空字符串和空模式匹配。
    • 对于空字符串 s,如果模式 p 能够匹配零个字符的情况(如 a*a*b*),则 dp[0][j] 需要根据前面字符的情况进行初始化。
  4. 最终结果dp[m][n] 表示 sp 的整体匹配结果。
动态规划算法的时间复杂度与空间复杂度:
  • 时间复杂度O(m * n),其中 m 是字符串 s 的长度,n 是模式 p 的长度。
  • 空间复杂度O(m * n),需要二维数组来保存中间结果。

步骤 4:算法优化启发

  1. 优化思路:在大型字符串和复杂模式下,可以通过滚动数组优化空间复杂度,将 dp 数组压缩为一维数组。通过观察,可以发现只需存储前一行的状态,因此可以用两个一维数组来交替更新,空间复杂度可以降低为 O(n)
  2. 效率提升:通过动态规划避免了递归或暴力回溯的重复计算问题,大大提升了处理大规模数据集的效率。

步骤 5:实际应用场景

正则表达式匹配算法在多个领域有广泛的应用,尤其在需要进行复杂模式匹配的场景中具有重要作用。以下是一个实际的应用场景:

实际应用示例:文本搜索和过滤

在大规模的文本数据处理中,正则表达式匹配被广泛用于日志分析、字符串匹配、敏感词过滤等。比如在 网络安全 领域,利用该算法可以在海量的日志文件中快速识别出潜在的攻击模式或特定的安全事件。

具体实现方法

  1. 日志系统通过正则表达式来过滤出具有攻击特征的日志条目。模式可能包含通配符(对应 .*)来捕捉多种变种攻击的表达方式。
  2. 通过优化后的动态规划算法,能够快速匹配出符合攻击模式的日志条目,提升整个安全系统的响应速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147330.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

TMS320F28335的定时器中断实验

TTMS320F28335 的 CPU 定时器有 3 个且均为 32 位,分别是 Timer0、Timer1、Timer2, 其中 Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普 通的定时器。这三个定时器的中断信号分别为 TINT0,TINT1,TINT2,分别对应中断向量于 INT1,INT13,INT14。 1 …

使用 NCache 将 Java 微服务扩展到极致性能

微服务已成为软件开发领域的一种变革性架构方法&#xff0c;提供了从整体结构到更加模块化和可扩展的系统的范式转变。微服务的核心是将复杂的应用程序分解为更小的、可独立部署的服务&#xff0c;这些服务可以无缝通信&#xff0c;从而提高敏捷性、灵活性和易维护性。这种分散…

动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结

动态规划day38|322. 零钱兑换&#xff08;背包满了吗&#xff1f;最小值怎么表示&#xff1f;&#xff09;、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结 322. 零钱兑换279. 完全平方数139. 单词拆分多重背包要点背包问题大总结 322. 零钱兑换 给你一个整数…

后端-项目创建与sql

1.创建文件 1.在webcontent下创建.html文件 2. 在java resources下创建包&#xff0c;右键包创建servlet服务生.(要是创建普通的类&#xff0c;里面的注解里的东西不能重复&#xff09; 注意&#xff1a;class的名字要和文件名一样&#xff0c;注解里的servlet是独一无二的。 …

最新 idea 2024 入门使用详细教程

IntelliJ IDEA&#xff1a;这是一款由JetBrains公司开发的Java集成开发环境&#xff08;Integrated Development Environment&#xff09;&#xff0c;被广泛认为是目前Java开发者最好的集成开发工具之一。它支持Java、Groovy、Kotlin等多种编程语言&#xff0c;并且提供了丰富…

HCIA--实验十七:EASY IP的NAT实现

一、实验内容 1.需求/要求&#xff1a; 通过一台PC&#xff0c;一台交换机&#xff0c;两台路由器来成功实现内网访问外网。理解NAT的转换机制。 二、实验过程 1.拓扑图&#xff1a; 2.步骤&#xff1a; 1.PC1配置ip地址及网关&#xff1a; 2.AR1接口配置ip地址&#xff1…

Java免税商品优选商城:Spring Boot实战

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterrise JavaBeans&#xff09;的全面支持&#xff0c;java servlet AI&#xff0c;JS&#xff08;java server ages&#xff09…

Tomcat中BIO和NIO的区别(Tomcat)

BIO Tomcat中BIO的模型和理论很简单&#xff0c;例图如下 1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求 2.接收到请求之后打包成一个SocketProcessor&#xff08;Runnable&#xff09;&#xff0c;扔到线程池中读取/写入数据 参数配置 1.Acceptor默认线程是1&#…

2024年1月Java项目开发指南17:自动接口文档配置

Knife4j 文档 &#xff1a;https://doc.xiaominfo.com/ 有能力的建议自己去看文档配置&#xff0c;本文仅做参考&#xff0c;因为官方文档会更新&#xff0c;本文不会&#xff0c;以后说不定本文就过时了。 ok&#xff0c;我们继续。虽然本文是2024年1月Java项目开发指南17&…

JVM面试题-说一下JVM主要组成部分及其作用

总体来说&#xff0c;方法区和堆是所有线程共享的内存区域&#xff1b;而虚拟机栈、本地方法栈和程序计数器的运行是线程私有的内存区域&#xff0c;运行时数据区域就是我们常说的JVM的内存。 类加载子系统&#xff1a;根据给定的全限定名类名(如&#xff1a;java.lang.Object…

使用Kong开源API网关的保姆级教程

什么是Kong? Kong是一个开源的、云原生、高性能的API网关,可以轻松地为任何服务提供管理、保护和扩展。它提供了一个可扩展的插件生态系统,可以满足各种各样的需求,如身份验证、授权、限流、监控等。 安装Kong 1. 环境准备 操作系统: CentOS、Ubuntu等主流Linux发行版D…

微信小程序IOS真机调试-onPullDownRefresh和onReachBottom不生效

切换真机调试2.0版本 勾选JS编译成ES5 如果使用了 uniapp&#xff0c;这里也需要勾选 重新启动

【Proteus单片机仿真】基于51单片机的循迹小车避障+气体传感器和温度传感器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 开机即两个直流电机运转&#xff0c;然后三个气体传感器&#xff0c;如果超过阈值&#xff0c;即蜂鸣器报警&#xff1b; 超声波传感器&#xff0c;如果检测到障碍&#xff0c;电机停止&#xff1…

深度学习02-pytorch-06-张量的形状操作

在 PyTorch 中&#xff0c;张量的形状操作是非常重要的&#xff0c;可以让你灵活地调整和处理张量的维度和数据结构。以下是一些常用的张量形状函数及其用法&#xff0c;带有详细解释和举例说明&#xff1a; 1. reshape() 功能: 改变张量的形状&#xff0c;但不改变数据的顺序…

[Redis][List]详细讲解

目录 0.前言1.常用命令1.LPUSH / RPUSH2.LPUSHX / RPUSHX3.LRANGE4.LPOP / RPOP5.LINDEX6.LINSERT7.LLEN8.LREM9.LTRIM10.LSET 2.阻塞版本命令0.是什么&#xff1f;1.BLPOP / BRPOP 3.内部编码(旧版本&#xff0c;仅供参考)1.ziplist(压缩链表)2.linkedlist(链表)3.quicklist(快…

TK72A12N1 N沟道功率MOSFET 工业控制领域的高性能功率开关

TK72A12N1产品特性&#xff1a; 漏源电压&#xff08;Vdss&#xff09;&#xff1a;120V&#xff0c;这意味着该器件在正常工作时&#xff0c;漏极和源极之间所能承受的最大电压为 120V。如果超过这个电压&#xff0c;可能会导致器件损坏。 漏极电流&#xff08;Id&#xff0…

基于SpringBoot和Vue框架的医保管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 1.研究的主要内容与方法 &#xff08;1&#xff09;主要内容 医保管理系统采用B/S模式进行开发&#xff0c;采用Springboot框架、VUE技术、Idea为环境、MySQL为数据库开发。主要功能有&#xff1a;个人资料管理、投保用户管理、…

C++ 把字符串转换成整数 (atoi) - 力扣(LeetCode)

点击链接即可查看&#xff1a;LCR 192. 把字符串转换成整数 (atoi) - 力扣&#xff08;LeetCode&#xff09; 一、题目 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 my…

剩余参数运算符的babel转义配置

记一次生产构建的报错 uncaught syntaxerror: unexpected token ... 背景 在处理展示markdown文本功能&#xff0c;并且其中的代码高亮功能时&#xff0c;引入了两个第三发的依赖包marked 和 highlight.js &#xff0c;本地功能调试正常之后&#xff0c;一如即往的没有build…

基于51单片机的汽车倒车防撞报警器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 本课题基于微控制器控制器&#xff0c; 设计一款汽车倒车防撞报警器系统。 要求&#xff1a; 要求&#xff1a;1.配有距离&#xff0c; 用于把车和障碍物之间的距离信号送入控制器。 2.配有报警系…