动态规划:LeetCode第10题 正则表达式匹配

news2024/10/5 16:21:41

题目:

给你一个字符串 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、字符串是否匹配取决于字符串每一位的匹配结果,如果前一位字符都不匹配,则后续将不会再匹配了,所以适合动态规划的结题思路,也即:后面的结果可以由前面的结果推导出来

2、因为字符串匹配是两个字符串,所以采用二维的动态规划

3、*匹配零个或多个前面的那一个元素,这个是结题的关键,尤其是匹配零个,这个经常让我们忽略,比如下例:

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

输出:True 

解释:"b" 后面有*,表示b出现了0次。

动态规划的状态转移方程:

我们用 f[i][j]表示 s的前 i个字符与 p中的前 j 个字符是否能够匹配。

在进行状态转移时,我们考虑 p 的第 j 个字符的匹配情况:

1、如果 p 的第 j 个字符是一个小写字母( '.' 匹配任意一个字母,可以看成一个特殊的字母),那么我们必须在 s 中匹配一个相同的小写字母,若相等,只需判断 i,j 之前的字符串是否匹配即可,也就转化为子问题 f[i-1][j-1],若不等,则当前的 i,j 肯定不能匹配,则f[i][j]= false.即可写出公式:

2、如果 p 的第 j 个字符是 *,那么就表示我们可以对 p 的第 j−1 个字符匹配0次或多次,则不妨把类似 'a*', 'b*' 等的当成整体看待:

2.1、如果p[j-1]与s[i]不匹配,那么f[i][j]的匹配情况需要看 f[i][j-2],也就是a*匹配0次(等于没出现a*)的情况,那么也就转化为子问题 f[i][j-2]

2.2、如果p[j-1]与s[i]匹配

2.2.1、最先想到的是一种情况:因为s[i]已经与p[j-1]匹配了,所以我们要看s[i]与p[j−2]的匹配,也就是转化为子问题:f[i][j-2]

2.2.2、其次还有一种情况:2.2.1考虑的是p[j]是p[j-1]重复的情况,本场景需要考虑的是s[i]与s[i-1]相同的情况,那就看s[i−1]与p[j] 的匹配,也就是转化为子问题:f[i-1][j]

2.2.3、综上,那么即可写出公式:

3、最终的状态转换方程如下:

4、状态初始化:

4.1、动态规划的边界条件为 f[0][0]=true,f[n][0](n>0)=false,也就是空字符串s与空字符串p相等,而任何的非空字符串s与空字符串p与都不相等。有人会问,为什么空字符串s能与非空字符串p相等呢?因为 a*能匹配空字符串,此时表示0次匹配。

Python代码:

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        sL = len(s)
        pL = len(p)
        f = [[False for j in range(pL + 1)] for i in range(sL + 1)]
        f[0][0] = True
        for i in range(0, sL + 1):
            for j in range(1, pL + 1):
                if p[j - 1] != '*':
                    if match(s,i,p,j):
                        f[i][j] = f[i -1][j - 1]
                else:
                    if match(s,i, p ,j -1):
                        f[i][j] = f[i - 1][j] or f[i][j - 2]
                    else:
                        f[i][j] = f[i][j - 2]
        return f[sL][pL]
        
def match(s, i, p, j):
    if s[i - 1] == p[j - 1]:
        return True
    if p[j - 1] == '.':
        return True
    return False



        

总结:

1、动态规划是逆向思考问题,从后往前进行归纳,也就是思考f(n+1)是如何由f(n)得到的问题

2、动态规划方程的初始化也需要思考清楚,相关的边界条件要想好

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

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

相关文章

express+mysql+vue,从零搭建一个商城管理系统10--添加商品

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、新建models/goods.js二、新建routes/goods.js三、添加goods表四、添加商品总结 前言 需求&#xff1a;主要学习express&#xff0c;所以先写service部分 一、新建models/goods.js models/goods.js con…

(二十一)从零开始搭建k8s集群——kubernates核心组件及功能介绍

前言 Kubernetes是一个可移植、可扩展、开源的平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;它促进了声明性配置和自动化。Kubernetes容器可以持续开发、集成和部署&#xff1a;可靠且频繁地构建和部署容器镜像&#xff0c;快速有效地回滚&#xff1b;开发与运…

【MGR】MySQL Group Replication快速开始

目录 17.2 Getting Started 17.2.1 Deploying Group Replication in Single-Primary Mode 17.2.1.1 Deploying Instances for Group Replication 17.2.1.2 Configuring an Instance for Group Replication Storage Engines Replication Framework Group Replication Sett…

【Git】项目源码迁移到另一个gitlab(保留原来提交历史记录)

目录 前情提要迁移方案IDEA远程仓库管理团队其他成员切换gitgit命令操作界面 前情提要 公司原来是自己私有部署的gitlab。有了研发云后就希望将代码推送到研发云的代码仓库上。这时候需要迁移并保留原来提交的历史记录。 迁移方案 登录新的gitlab(代码仓库)新建空白项目获取…

hive sql无法停止

排查流程 hive任务停止是调用org.apache.hive.jdbc.HiveStatement的close()方法实现的 其底层是委托给org.apache.hive.service.cli.thrift.TCLIService.Iface客户端实例来实现。 同时&#xff0c;通过JDK动态代理为其织入了synchronized同步机制&#xff1a;其底层是委托给…

进入软件测试行业,这些问题你一定要知道!

很多转行的朋友都会选择进入软件测试开发行业&#xff0c;如果确定进入软件测试开发行业&#xff0c;那么这些问题你一定要知道&#xff01; 一、软件测试发展前景 1、测试人员与开发人员的配比已经从最初的1:10、1:8&#xff0c;发展到如今的1:3、1:2。未来会继续趋于平衡&…

flink重温笔记(十):Flink 高级 API 开发——flink 四大基石之 State(涉及Checkpoint)

Flink学习笔记 前言&#xff1a;今天是学习 flink 的第 10 天啦&#xff01;学习了 flink 四大基石之 State &#xff08;状态&#xff09;&#xff0c;主要是解决大数据领域增量计算的效果&#xff0c;能够保存已经计算过的结果数据状态&#xff01;重点学习了 state 的类型划…

ABAP - SALV教程12 显示图标和提示信息

ALV要求字段的值为图标的需求并不多见&#xff0c;一般都用于红黄绿灯&#xff0c;来表示单据的执行状态&#xff0c;添加图标的方式也可以实现红黄绿灯的功能&#xff0c;也可以参考SALV实现红黄绿灯这篇文章&#xff1a;http://t.csdnimg.cn/Dzx7x效果图SAVL列设置为图标图标…

1688淘宝天猫无货源API(商品列表、商品详情、店铺商品、sku)

item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论item_search 按关键字搜索淘宝商品item_search_img 按图搜索淘宝商品&#xff08;拍立淘&#xff09;item_search_shop 获得店铺的所有商品item_search_seller 搜索店铺列表 API公共…

【LeetCode】升级打怪之路 Day 13:优先级队列的应用

今日题目&#xff1a; 23. 合并 K 个升序链表 | LeetCode378. 有序矩阵中第 K 小的元素 | LeetCode373. 查找和最小的 K 对数字 | LeetCode703. 数据流中的第 K 大元素 | LeetCode347. 前 K 个高频元素 | LeetCode 目录 Problem 1&#xff1a;合并多个有序链表 【classic】LC 2…

一些硬件知识(五)

选择MCU时需要考虑以下几个方面&#xff1a;1。首先考虑引脚功能数量是否够用2.其次如果跑RTOS操作系统的话对堆栈有要求3.需要考虑单片机某个功能的极限性能&#xff0c;例如做BLDC驱动板子的时候要求对电机的电流做到精确采样&#xff0c;此时会选用这个方向表现较好的MCU,例…

如何搭建Nacos集群

1.搭建Nacos集群 众所周知&#xff0c;在实际的工作中&#xff0c;Nacos的生成环境下一定要部署为集群状态 其中包含3个nacos节点&#xff0c;然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。 我们计划的集群结构&#xff1a; 我就直接在本机上开三个Nacos来搭…

变分推断中的ELBO(证据下界)

一、变分推断简介 变分推理的目标是近似潜在变量(latent variables)在观测变量(observed variables)下的条件概率。解决该问题,需要使用优化方法。在变分推断中,需要使用到的一个重要理论,是平均场理论。 1、平均场理论 来源于物理学,是一种研究复杂多体问题的方法,将…

Rust 中如何解析 JSON?

Rust 中如何解析 JSON? 在本文中&#xff0c;我们将讨论如何在 Rust 中使用 JSON 解析库&#xff0c;以及比较最流行的库及其性能。 JSON 解析基础知识 手动解析 JSON 要开始在 Rust 中使用 JSON&#xff0c;您需要安装一个可以轻松操作 JSON 的库。目前可用的流行crate之一…

07 系统的线性时不变特性

各位看官&#xff0c;大家好&#xff01;本讲为《数字信号处理理论篇》07 系统的线性时不变特性。&#xff08;特别提示&#xff1a;课程内容为由浅入深的特性&#xff0c;而且前后对照&#xff0c;不要跳跃观看&#xff0c;请按照文章或视频顺序进行观看。 从本讲开始开始为大…

【Python】进阶学习:__len__()方法的使用介绍

【Python】进阶学习&#xff1a;__len__()方法的使用介绍 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

shadertoy 游戏《来自星尘》摇杆复刻

正确的做法应该是上 noise 而不是叠加 sin 波&#xff0c;不过如果不想麻烦的话叠波还是一个不错的选择&#xff1a;整体效果如下&#xff0c;已经非常形似 直接上链接&#xff1a;Shader - Shadertoy BETA float radiusScale 0.9; float variation(vec2 v1, vec2 v2, float …

KCV(Key Check Value)的作用(验证密钥导入是否正确)与算法(DES/3DES或AES)示例

KCV的作用与算法 KCV&#xff08;Key Check Value&#xff09;的计算通常与加密算法有关&#xff0c;不同算法计算KCV的方式不同。以下是常见算法的KCV计算方法&#xff1a; DES/3DES算法&#xff1a; KCV是通过使用ECB模式的3DES加密8字节’00’来计算的。例如&#xff0c;…

【鸿蒙 HarmonyOS 4.0】弹性布局(Flex)

一、介绍 弹性布局&#xff08;Flex&#xff09;提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。容器默认存在主轴与交叉轴&#xff0c;子元素默认沿主轴排列&#xff0c;子元素在主轴方向的尺寸称为主轴尺寸&#xff0c;在交叉轴方向的尺寸称为交叉轴尺寸…

Pipy 进化:从可编程代理到应用引擎

网络功能变得越来越复杂&#xff0c;编写和维护的难度提升&#xff1b;新的基于 Pipy 的应用中&#xff0c;Pipy 角色从数据平面变成控制面&#xff0c;需要执行更多复杂非网络的逻辑&#xff1b;从长远来看&#xff0c;Pipy 将更像是一个常见的类似 shell/bash 的系统脚本工具…