(leetcode算法题)10. 正则表达式匹配
10. 正则表达式匹配 - 力扣(LeetCode)
此题的要求一个字符串 s 和一个字符规律 p之间支持 '.' 和 '*' 的正则表达式匹配
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。
保证每次出现字符 * 时,前面都匹配到有效的字符 也就是说p中所有的 * 字符前的那个字符只会是 . 或者字母
示例 1: 输入:s = "a", p = ".*" 输出:true
示例 2: 输入:s = "aab", p = "c*a*b" 输出:true
示例 3: 输入:s = "a", p = "a*" 输出:true
示例 4: 输入:s = "a", p = ".*a" 输出:true
根据经验和题目要求,两个字符串的关系可以考虑二维dp表,
能够解决的leetcode中的1143. 最长公共子序列、72. 编辑距离中dp的建立相似,
dp[i][j]表示p[0.j]区间内的子串是否能够匹配s[0,i]区间内的子串
状态转移方程:根据 p 切出来的子串中的最后一个字符来分情况讨论,这种按两个子串的最后一个字符的取值来分情况讨论的方式,也是推导状态转移方程的普遍步骤,
记记dp[i][j] = x; dp[i - 1][j] = y; dp[i][j - 2] = z dp[i - 1][j - 1] = w
则当p[j - 1] 为字母或者 点号时,
只用通过 w 和 (s[i - 1] == p[j - 1] || p[j - 1] == '.')这个表达式是否为真就能更新dp[i][j]
当p[j - 1] 为星号时,
只用通过y 和 z 和(s[i - 1] == p[j - 2] || p[j - 2] == '.') 这个表达式是否为真就能更新dp[i][j]

图一
读者可能会问了,道理我都懂,为什么使用了dp[i][j - 2] 来更新dp[i][j],而dp[i][j - 1]却没有使用?

让我们来看看图一中 出现p[j - 1] == '*' && p[j - 2] == '.' 的情况
此时可以选择产生空串,或者将产生一个点号、两个点号,等等
那么dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || ... dp[i - m][j - 2] || ... (1)
令i = u - 1
则有dp[u - 1][j] = dp[u - 1][j - 2] || dp[u - 2][j - 2] || ... dp[u - m - 1][j - 2] || ... (2)
观察可知,可将(2)代入(1)中得到
dp[i][j] = dp[i][j - 2] || dp[i - 1][j]
让我们再来看看图一中 出现p[j - 1] == '*' && p[j - 2] != '.' 的情况
此时可以选择产生空串,或者将产生一个p[j - 1]、两个p[j - 1],等等
那么
dp[i][j] = dp[i][j - 2] || ((s[i -1] == p[j - 2]) && (dp[i - 1][j - 2])) || ... ((s[i - m] == p[j - 2]) && dp[i - m][j - 2] ) || ... (3)
令i = v - 1
则有dp[v - 1][j] = dp[v - 1][j - 2] || ( (s[v - 2] == p[j - 2]) && (dp[v - 2][j - 2]) ) || ... ( (s[v - m - 1] == p[j - 2]) && (dp[v - m - 1][j - 2]) ) || ... (4)
观察可知,可将(4)代入(3)中,然后经过一些列的推导(具体步骤略),可以得到
dp[i][j] = dp[i][j - 2] || ( (s[i -1] == p[j - 2]) && dp[i - 1][j])
知道这道题为什么用到了dp[i][j - 2]了吧,但是还有一个很重要的问题,就是在编写这道题的程序的时候,可以给这个dp表多加一行,多加一列,所以
上面在访问原数组是 s[i - 1] 代表的就是第 i 个元素
那么多加的这一行/列是否可以赋予这个题目场景下的具体意义呢?
多加的一行,可以赋予dp[0][j] 一个意义,其意义就是s作为一个空串,匹配p[0, j]
如果在这种定义下,dp[0][j]要想为true,j 和 p[j] 必须满足以下条件才能保证匹配
dp[0, j] 是形如 {{非星号}{星号} {非星号}{星号} {非星号}{星号} {非星号}{星号}}
而dp[i][0] 此时只有在dp[0][0]处会为true
class Solution {
public:bool isMatch(string s, string p) {int len1 = s.size();int len2 = p.size();vector<vector<bool>> dp(len1 + 1, vector<bool>(len2 + 1, false));dp[0][0] = true;for(int j = 2; j <= len2; j += 2){if(p[j - 1] == '*'){dp[0][j] = true;}else{break;}}for(int i = 1; i <= len1; ++i){for(int j = 1; j <= len2; ++j){if(p[j - 1] != '*'){dp[i][j] = ((p[j - 1] == s[i - 1] || p[j - 1] == '.') && dp[i - 1][j - 1] == true);}else{dp[i][j] = ((dp[i][j - 2] == true) || ((p[j - 2] == s[i - 1] || p[j - 2] == '.') && (dp[i - 1][j] == true)));}}}return dp[len1][len2];}
};
相关文章:
(leetcode算法题)10. 正则表达式匹配
10. 正则表达式匹配 - 力扣(LeetCode) 此题的要求一个字符串 s 和一个字符规律 p之间支持 . 和 * 的正则表达式匹配 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串…...
SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)
一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…...
使用爬虫技术获取网页中的半结构化数据
目录 前言1. 半结构化数据与爬虫技术简介1.1 半结构化数据的定义与特性1.2 爬虫技术的基本原理 2. 爬取半结构化数据的实现过程2.1 明确目标与准备2.2 发送HTTP请求2.3 解析网页内容2.4 动态内容的处理2.5 数据存储与清洗 3. 技术挑战与应对策略3.1 处理反爬机制3.2 提高爬取效…...
2025/1/1 路由期末复习作业二
呼呼呼祝大家元旦节快乐啦!(我顶着我超重的黑眼圈说) 昨天一个人在寝室一边吃泡面,一边看步步惊心,一边吃一边哭呜呜呜呜呜若曦为什么不和八爷在一起好好爱,就因为他不当皇帝蛮!难测最是帝王心…...
OpenCV-Python实战(13)——图像轮廓
一、找轮廓 cv2.findContours() contours,hierarchy cv2.findContours(image*,mode*,method*) contours:找到的所有轮廓数组,数组内的元素为轮廓像素点坐标。 hierarchy:轮廓间的层次关系。 image:二值图像(cv2.t…...
javascript变量
变量 命名规范 以 字母、数字、下划线、美元符号 $ 组成、不能以 数字开头、且不能使用 js 中的关键字。 命名规范推荐采用小驼峰 命名法 。类名 采用 大驼峰命名。 var 声明变量的特点 在 script 上下文中定义的是 全局变量,全局变量会自动称为 window的属性。 在…...
在K8S中,如何查看kubelet组件的日志?
在kubernetes中,查看Kubelet组件的日志可以通过几种不同的方法。以下是详细的步骤: 1. 使用journalctl命令: 如果kubelet是通过systemd方式部署,你可以使用journalctl命令来查看其日志。执行journalctl -u kubelet将显示Kubelet…...
android studio android sdk下载地址
android studio安装后,因为公司网络原因,一直无法安装android sdk 后经过手机网络,安装android sdk成功如下,也可以手动下载后指定android sdk本地目录 https://dl.google.com/android/repository/source-35_r01.zip https://dl…...
Fetch处理大模型流式数据请求与解析
为什么有的大模型可以一次返回多个 data? Server-Sent Events (SSE):允许服务器连续发送多个 data: 行,每个代表一个独立的数据块。 流式响应:大模型服务通常以流式响应方式返回数据,提高响应速度。 批量处理&#x…...
FPGA自学之路:到底有多崎岖?
FPGA,即现场可编程门阵列,被誉为硬件世界的“瑞士军刀”,其灵活性和可编程性让无数开发者为之倾倒。但谈及FPGA的学习难度,不少人望而却步。那么,FPGA自学之路到底有多崎岖呢? 几座大山那么高?…...
从0到机器视觉工程师(二):封装调用静态库和动态库
目录 静态库 编写静态库 使用静态库 方案一 方案二 动态库 编写动态库 使用动态库 方案一 方案二 方案三 总结 静态库 静态库是在编译时将库的代码合并到最终可执行程序中的库。静态库的优势是在编译时将所有代码包含在程序中,可以使程序独立运行&…...
[极客大挑战 2019]Knife1
这里很显然,根据提示可以猜测,已经有一句话木马上传了,但是路径这里不是很清楚,不知道路径在哪里,不过还是用菜刀连一下试试: 连接成功,在根目录下发现flag。不过如果不用菜刀,可以用…...
【在Python中生成随机字符串】
在Python中生成随机字符串,你可以结合使用random模块和字符串操作。以下是一个常用的方法,通过从预定义的字符集中随机选择字符来构建字符串: import random import stringdef generate_random_string(length):# 定义字符集:可以…...
【three.js】场景搭建
three.js由场景、相机、渲染器、灯光、控制器等几个要素组成。每个要素都有不同的类型,例如光照有太阳光、环境光、半球光等等。每种光照都有不同的属性可以进行配置。 场景 场景(scene):场景是所有物体的容器,如果要…...
Singleton: WebRTC中ThreadManager中的单例模式
1. 什么是单例模式: 旨在确保一个类只有一个实例,并提供全局访问点。 应用场景:需要一个全局唯一的实例,避免资源浪费。 2. 单例模式的实现: Lazy Initialization(懒汉式)(延迟初…...
MySQL数据库笔记——多版本并发控制MVCC
大家好,这里是Good Note,关注 公主号:Goodnote,本文详细介绍MySQL的并发控制:多版本并发控制MVCC。 文章目录 背景介绍数据库并发控制——锁机制悲观锁和乐观锁悲观锁乐观锁 数据库并发控制——MVCC 的引入MVCC 和锁机…...
【0x0037】HCI_Write_Link_Supervision_Timeout命令详解
目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Write_Link_Supervision_Timeout 命令格式 2.2. Handle 2.3. Link_Supervision_Timeout 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 3.3. Handle 四、命令执行流程 4.1. 命令准备阶段 4.…...
Linux下如何进行内存泄漏分析
前言 正文 一、环境的安装 1、tar –xf valgrind-3.17.0.tar.bz2 2、cd valgrind-3.17.0 3、./configure // 运行配置脚本生成makefile文件,可以--help查看配置项,自行按需配置,比如修改编译工具、修改安装路径等 4、make 5、make…...
Colyseus Metadata 详解
Colyseus Metadata 详解 Colyseus 是一个专注于实时多人在线游戏和应用的框架,它的 metadata 功能为每个房间提供了一个灵活且有用的机制,用来存储和共享与房间相关的非实时信息。这些信息可以用来描述房间、标记房间状态、或提供额外的房间配置选项。 …...
C语言day5:shell脚本
一、练习题1 定义一个find函数,查找ubuntu和root的gid并使用变量接收结果 二、练习题2 定义一个数组,写一个函数完成对数组的冒泡排序 三、练习题3 使用break求1-100中的质数(质数:只能被1和它本身整除,如:…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
