【力扣算法03】之正则表达式匹配- python

news2024/11/15 2:21:08

文章目录

  • 问题描述
    • 示例 1
    • 示例2
    • 示例3
    • 提示
  • 思路分析
  • 代码分析
  • 完整代码
    • 运行效果及示例代码
      • 示例代码1
      • 运行结果
      • 示例代码2
      • 运行结果
      • 示例代码3
      • 运行结果
  • 完结

问题描述

在这里插入图片描述

给你一个字符串 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 的小写字母,以及字符 . 和 *。
  • 保证每次出现字符 * 时,前面都匹配到有效的字符

思路分析

请添加图片描述

首先, 创建一个二维数组dp,其中dp[i][j]表示字符串s的前i个字符与模式p的前j个字符是否匹配。
初始化dp[0][0]True,因为空字符串与空模式是匹配的。
接下来, 需要填充数组dp的其他值。我们使用两个嵌套的循环来遍历字符串s和模式p的每个字符。
对于每个位置(i, j),我们考虑几种情况:

  1. 如果模式p的当前字符p[j-1]不是*,我们只需要判断字符串s的当前字符s[i-1]和模式p的当前字符p[j-1]是否匹配。如果相等,或者p[j-1].通配符,我们可以将dp[i][j]设置为dp[i-1][j-1],表示前缀字符串匹配。
  2. 如果模式p的当前字符p[j-1]*,我们需要考虑两种情况:
    • *代表0个前面的字符。在这种情况下,我们将dp[i][j]设置为dp[i][j-2],表示模式p中的p[j-2]p[j-1]被忽略。
    • *代表多个前面的字符。我们需要检查字符串s的当前字符s[i-1]和模式p的前一个字符p[j-2]是否匹配。如果匹配,我们可以将dp[i][j]设置为dp[i-1][j],表示可以将当前字符*匹配到字符串s的前一个字符。

最终,返回dp[m][n]的值,其中m为字符串s的长度,n为模式p的长度。如果dp[m][n]True,则表示整个字符串s与模式p匹配;否则,不匹配。

代码分析

在这里插入图片描述

def isMatch(self, s: str, p: str) -> bool:
    m = len(s)
    n = len(p)
    dp = [[False] * (n + 1) for _ in range(m + 1)]
    dp[0][0] = True
  • 首先,我们定义了一个isMatch函数,接受两个参数sp,分别表示字符串和模式。
  • 然后,我们获取字符串s和模式p的长度,并创建大小为(m+1) x (n+1)的二维数组dp,并将所有元素初始化为False
  • 初始化dp[0][0]True,因为空字符串与空模式是匹配的。
    for i in range(m + 1):
        for j in range(1, n + 1):
            if p[j - 1] != '*':
                if i > 0 and (s[i - 1] == p[j - 1] or p[j - 1] == '.'):
                    dp[i][j] = dp[i - 1][j - 1]
            else:
                if j >= 2:
                    dp[i][j] = dp[i][j - 2]
                    if i > 0 and (s[i - 1] == p[j - 2] or p[j - 2] == '.'):
                        dp[i][j] |= dp[i - 1][j]
  • 使用两层循环遍历字符串s和模式p的每个字符。
  • 对于每个位置(i, j),我们分情况讨论:
    • 如果模式p的当前字符p[j-1]不是*,且字符串s的当前字符s[i-1]与模式p的当前字符p[j-1]匹配(或者p[j-1].通配符),则将dp[i][j]设置为dp[i-1][j-1],表示前缀字符串匹配。
    • 如果模式p的当前字符p[j-1]*,我们需要进一步分情况讨论:
      • *代表0个前面的字符:设置dp[i][j]dp[i][j-2],表示模式p中的p[j-2]p[j-1]被忽略。
      • *代表多个前面的字符:首先设置dp[i][j]dp[i][j-2],然后判断字符串s的当前字符s[i-1]与模式p的前一个字符p[j-2]是否匹配。如果匹配,就将dp[i][j]更新为dp[i-1][j]的值。
    return dp[m][n]
  • 最后,返回dp[m][n]的值,即表示整个字符串s与模式p是否匹配。

完整代码

在这里插入图片描述

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        # 获取字符串s和模式p的长度
        m, n = len(s), len(p)
        
        # 创建一个二维dp数组来存储匹配结果,默认为False
        dp = [[False] * (n + 1) for _ in range(m + 1)]
        
        # 初始化dp[0][0]为True,表示空字符串与空模式匹配
        dp[0][0] = True

        for i in range(m + 1):
            for j in range(1, n + 1):
                if p[j - 1] != '*':
                    # 当前字符不是'*'时,比较s的第i个字符和p的第j个字符是否匹配
                    if i > 0 and (s[i - 1] == p[j - 1] or p[j - 1] == '.'):
                        dp[i][j] = dp[i - 1][j - 1]
                else:
                    # 当前字符是'*'时,分两种情况考虑
                    # 第一种情况:忽略p的前两个字符(即'*'前面的字符)
                    if j >= 2:
                        dp[i][j] = dp[i][j - 2]
                    # 第二种情况:如果s的第i个字符和p的前两个字符匹配,
                    # 或者p的前两个字符是'.',则可以考虑将s的第i个字符加入匹配模式中
                    if i >= 1 and j >= 2 and (s[i - 1] == p[j - 2] or p[j - 2] == '.'):
                        dp[i][j] = dp[i][j] or dp[i - 1][j]

        # 返回匹配结果
        return dp[m][n]


运行效果及示例代码

示例代码1

 solution = Solution()
print(solution.isMatch("aa", "a"))

运行结果

在这里插入图片描述

示例代码2

 solution = Solution()
print(solution.isMatch("aa", "a*")) 

运行结果

在这里插入图片描述

示例代码3

 solution = Solution()
print(solution.isMatch("ab", ".*"))  

运行结果

在这里插入图片描述

完结

在这里插入图片描述

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

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

相关文章

企业省时又省力:人工智能电话客服机器人的广泛应用

人工智能技术的崛起正深刻地改变着各个行业&#xff0c;其中之一便是客服领域。过去&#xff0c;人们常常在电话中与生硬的自动语音应答机打交道&#xff0c;这种体验常常令人沮丧。然而&#xff0c;随着人工智能电话客服机器人的广泛应用&#xff0c;企业不仅能够省时又省力&a…

MYSQL数据库系统期末试题及参考答案(2)

期末试题 : 一&#xff0c;创建数据库Game 二&#xff0c;数据表操作 1、创建表格players&#xff0c;记录游戏玩家信息&#xff1a; player_id&#xff1a;玩家ID&#xff0c;主键 player_name&#xff1a;玩家姓名&#xff0c;不能为空 age&#xff1a;年龄&#xff0c;必须…

Python数据分析常见Matplotlib SeaBorn图表

Matplotlib绘图 Matplotlib基本概念 Matplotlib&#xff1a;基于对象的思维构建的视觉符号。 每一个Axes&#xff08;坐标轴&#xff09;对象包含一个或者多个Axis(轴)对象&#xff0c;比如X轴、Y轴。 一个Figure&#xff08;画像&#xff09;是由一堆坐标轴对象组成的。 换…

2023中国数交会|美创科技获数字和软件服务行业两项大奖!

7月6日-9日&#xff0c;为期四天的2023中国国际数字和软件服务交易会&#xff08;简称&#xff1a;数交会&#xff09;圆满落幕。 作为国务院批准举办的国家级展会&#xff0c;本届数交会由商务部、科技部、中国贸促会和辽宁省政府主办&#xff0c;以“数字创新、融合发展”为主…

操作系统实战45讲|03.黑盒之中有什么、04.震撼的Linux全景图

03.黑盒之中有什么 黑盒之中有什么 从抽象的角度来看&#xff0c;内核就是计算机资源的管理者&#xff0c;管理资源是为了让应用使用资源。 计算机中的资源分为两类&#xff1a;硬件资源、软件资源&#xff1b; 硬件资源有以下这些&#xff1a; 总线&#xff0c;负责连接各种…

一个Transformer在尺度上适合多模态扩散的所有分布

文章目录 One Transformer Fits All Distributions in Multi-Modal Diffusion at Scale摘要本文方法实验结果 One Transformer Fits All Distributions in Multi-Modal Diffusion at Scale 摘要 本文提出了一个统一的扩散框架(UniDiffuser)来拟合一个模型中与一组多模态数据相…

Vue3+Vite+Pinia+Naive后台管理系统搭建之三:vue-router 的安装和使用

前言 如果对 vue3 的语法不熟悉的&#xff0c;可以移步 Vue3.0 基础入门快速入门。 如果对 vue-router 语法不熟悉的&#xff0c;可以移步Vue3 系列&#xff1a;vue-router。 1. 安装依赖 yarn add vue-router // or npm install vue-router 2. 构建 src/router/index.js …

对话式ai人工智能的主要好处有哪些

对话式 AI 是客户服务的一个重要且不断增长的组成部分&#xff0c;尤其是客户越来越多地采用的数字自助服务。 对话式 AI 可以在提高客户满意度 (CSAT) 方面发挥很重要的作用。在 IBM 于 2021 年进行的一项研究中&#xff0c;99% 的公司报告称&#xff0c;由于使用虚拟对话式 …

支持源码的低代码核心工具,逻辑引擎

在现代企业管理中&#xff0c;决策扮演着至关重要的角色。然而&#xff0c;随着业务规模的扩大和数据量的增加&#xff0c;人工决策变得越来越困难和耗时&#xff0c;而且容易受到主观因素的影响。逻辑引擎的出现为企业提供了一种高效、准确的决策推理工具&#xff0c;能够以逻…

数字化转型迫在眉睫

在挑战商业世界现状并实现数字化转型时&#xff0c;一定程度的阻力是不可避免的。事实上&#xff0c;《福布斯》的一篇文章援引哈佛商学院的研究表明&#xff0c;70%的组织变革努力都失败了&#xff0c;“原因之一是高管们没有从足够多的人那里了解他们的计划和想法。”支持。”…

市面上的ipad国产触控笔怎么样?好用的电容笔合集

而对那些把IPAD当作学习工具的人而言&#xff0c;这个Apple Pencil绝对是不可或缺的。然而&#xff0c;苹果版本的Pencil却是昂贵得让许多人望而却步。因此&#xff0c;最佳方法是选择一个平替的电容笔。我是从几年前开始用IPAD的&#xff0c;也是一个数码爱好者&#xff0c;近…

AIGC行业周刊【2023-0709】【第六期】2023年世界人工智能大会大佬发言汇总

点击加入->【智子纪元-AIGC】技术交流群 一、大咖观点&#xff1a; 0709AI日报&#xff1a;2023年世界人工智能大会大佬发言汇总「5年内&#xff0c;人类程序员没了」&#xff0c;Stability AI老板大胆预测&#xff0c;一众大佬狂怼&#xff1a;大错特错&#xff0c;都懒得…

在vite创建的vue3项目中加载Cesium立体地形信息并调整初始化角度

在vite创建的vue3项目中加载Cesium立体地形信息并调整初始化角度 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium vite -D配置 &#xff08;1&#xff09;在项目的vite.config.js文件中添加&#x…

算法训练营第三十一天||理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

理论基础 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&#xff0c;你可以拿走十张&#xff0c;如果想达到最大的金额&#xff0c;你要怎么拿&#xff1f; 指定每次…

专项练习24

目录 一、选择题 1、JavaScript 中的数字在计算机内存中占多少个Byte&#xff1f; 2、请问以下JS代码会输出什么 二、编程题 1、以数字的形式返回数字参数向下取整的结果 一、选择题 1、JavaScript 中的数字在计算机内存中占多少个Byte&#xff1f; A、2 Byte B、4Byte C…

如何在购物 App 上实现商品快递物流信息的展示

前言 现如今&#xff0c;人们大多数会选择在手机购物App上进行购物&#xff0c;这样买东西很是便捷&#xff0c;不用出门就能买到全国各地甚至是国外的商品&#xff0c;下单之后只需要等待快递送达就可以了。一个购物APP&#xff0c;不可或缺的一个辅助功能就是&#xff0c;展…

GPT-4 验明真身的经典三连问:快速区分 GPT-3.5 与 GPT-4

GPT-4 验明真身的经典三连问&#xff1a;快速区分 GPT-3.5 与 GPT-4

华为VRP系统基础

系列文章目录 华为数通学习&#xff08;1&#xff09; 目录 一&#xff0c;什么是VRP? 二&#xff0c;VRP的发展 三&#xff0c;VRP的文件系统 3.1&#xff0c;系统文件:.cc结尾 ​编辑 3.2&#xff0c;配置文件&#xff1a;.cfg&#xff0c;.zip&#xff0c;.dat结尾 3.…

统计年,月,日,java补充无的数据

需求&#xff1a;营收趋势图。需要按年&#xff0c;按月&#xff0c;按日。按年&#xff0c;后方选择日历 起始年-结束年。例如start2013 end 2023 按月&#xff0c;后方选择月份 起始月-结束月。例如start 2022-10 end 2023-07。 按日&#xff0c;后方选择日 起始日-结束日。例…

Vue-CodeMirror 使用

vue2 安装 npm install vue-codemirror -S # or yarn add vue-codemirror -S 全局配置&#xff0c;main.js文件引入 import VueCodemirror from vue-codemirror // import base style import codemirror/lib/codemirror.css Vue.use(VueCodemirror)Vue 文件内使用 <templ…