leetcode 10. 正则表达式匹配

2023-11-14

2023.9.20

        感觉是目前做过dp题里最难的一题了...

        本题首要的就是需要理解题意,翻了评论区我才发现之前一直理解的题意是错的。 我原来理解的 “ *匹配0次” 是指:*直接消失,不会影响到前面的字符。  但是*和前一个字符其实是连体的,所以说:*如果匹配0次,那么前一个字符就没了,消失了;*如果匹配1次,那么才相当于*消失了,不影响前面的字符;也就是说: *如果匹配n次,相当于前一个字符会出现n次。

        理解了题意之后再来用dp算法做这道题。本题用的是二维bool型dp数组,dp[i][j]含义是:字符串s的前i个字符 和 字符串p的前j个字符 能否匹配。

        再来看核心的递推公式。遍历的时候分为两种情况:

①s和p 的当前字符相等(这个相等包括p的当前字符是“_”,也算一种相等嘛!):那么可以想象一下,当前这两个字符相等了,像消消乐一样两字符消掉,两个指针各退一步,指向各自的前一个字符,当前dp数组的状态 转化为 之前dp数组的状态。即:dp[i][j] = dp[i - 1][j - 1];

②s和p 的当前字符不相等:两字符不相等了,还有补救措施,那就是p的字符如果为*的话,还有机会匹配。 那么此时又分为两种子情况:

  • 当p的当前字符为"*"时:此时需要先判断一下*前面的字符和s的当前字符相不相等。如果不相等,说明*只能带着前面的字符一起消失了,即匹配0个:dp[i][j] = dp[i][j - 2];  如果相等的话:那么*可以匹配0次、也可以匹配1次、也可以匹配多次,即dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
  • 当p的当前字符不为“*”时:那么直接就是false就行了,不过构建dp数组时是将所有位置都初始化为false了,所以这一步可以省略。

        最后,dp[0][0]需要初始化为true,因为空字符串肯定是能匹配的嘛! 但是运行的时候有一个案例通不过:s=“aab”,p=“c*a*b” 。 翻看了评论区:有个方法就是分别在s和p之前加个空格:即

        s = " " + s;

        p = " " + p;

        最后上代码:

class Solution {
public:
    bool isMatch(string s, string p) {
        s = " " + s; 
        p = " " + p;
        vector<vector<bool>> dp(s.size() + 1, vector<bool>(p.size() + 1, false));
        dp[0][0] = true;
        for (int i = 1; i <= s.size(); i++) 
        {
            for (int j = 1; j <= p.size(); j++) 
            {
                //字符相同,或者p字符有万能符号。 (万能符号也可以理解为两字符相等)
                if (s[i - 1] == p[j - 1] || p[j - 1] == '.') 
                {
                    dp[i][j] = dp[i - 1][j - 1];
                } 
                else if (p[j - 1] == '*') 
                {
                    if (s[i - 1] == p[j - 2] || p[j - 2] == '.') 
                    {
                        dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];//分别对应*匹配1次、0次、多次的情况。
                    } 
                    else 
                    {
                        dp[i][j] = dp[i][j - 2]; //p字符串*号前面的字符 和 s字符串当前字符 不相等,只能让*匹配0次。
                    }
                }
            }
        }
        return dp[s.size()][p.size()];
    }
};

        

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

leetcode 10. 正则表达式匹配 的相关文章

随机推荐

  • WebView 加载不出网页,一片空白

    今天在项目上加载网页时 发现一只加载不出来 emmm 就看了下以往的项目 发现遗漏的地方不止一点哦 在此做个总结 1 权限配置 确保在 AndroidManifest xml 文件中添加了网络权限
  • python函数修饰器定义不调用、会执行吗_Python/函数装饰器概念(详解)

    Python中装饰器的概念 装饰器 Decorators 是 Python 的一个重要部分 简单地说 他们是修改其他函数的功能的函数 他们有助于让我们的代码更简短 也更Pythonic Python范儿 大多数初学者不知道在哪儿使用它们 所
  • UVM基础知识3:Systemverilog 验证 12.2.2实例

    来源 systemverilog验证 测试平台编写指南 书籍 1 新建counter7 c文件 vi counter7 c include
  • 离散数学知识点总结(6):自然推理系统;13 个推理规则; 如何使用推理规则

    文章目录 自然推理系统的定义 13个推理规则 如何在自然推理系统中构造有效论证的方法 直接证明法 附加前提证明法 cp规则 反证法 归谬法 Proofs by Contradiciton 对位证明 Proofs by contraposit
  • [转][学习]软件绿色联盟应用体验标准5.0_功耗标准-公示版

    文档来源 软件绿色联盟 软件绿色联盟应用体验标准5 0 功耗标准 公示版 pdf 软件绿色联盟官方 下载网址 https www china sga com index html 软件绿色联盟应用体验标准 5 0 功耗标准 编制单位 软件绿
  • 优化Mysql数据库的8个方法

    本文通过8个方法优化Mysql数据库 创建索引 复合索引 索引不会包含有NULL值的列 使用短索引 排序的索引问题 like语句操作 不要在列上进行运算 不使用NOT IN和 lt gt 操作 1 创建索引 对于查询占主要的应用来说 索引显
  • flyway出现org.flywaydb.core.api.FlywayException: Validate failed:问题解决办法

    在idea中找到数据库 如下图所示 双击flyway出现执行 mvn flyway migrate 历史记录 把最新执行看到执行失败的那条记录删掉 并提交 然后重新运行mvn flyway migrate 命令即可成功
  • Mybatis---配置文件元素属性详解

    Mybatis配置文件详解 Mybatis配置文件层次结构层次结构顺序不能改变否则会报错 Properties子元素 设置settings 类型别名typeAliases 系统定义别名 自定义别名 typeHandler类型处理器 系统定义
  • nginx代理yum

    适用场景 有多台服务器 但是只有1台服务器可以出公网 此时即可使用如下方式 进行yum代理 解决内网服务器不能yum的尴尬 一 首先需要把 etc yum repos d下的文件备份到bak 然后留一个CentOS Base repo 编辑
  • 农夫过河——python类穷举法实现

    一个农夫在河的西岸带了一匹狼 一只羊和一棵白菜 他需要把这三样东西用船带到河的东岸 然而 这艘船只能容下农夫本人和另外一样东西 如果农夫不在场的话 狼会吃掉羊 羊也会吃掉白菜 w 1 2 3 西岸初始状态 0代表没有 1代表白菜 2代表羊
  • 编译、安装和使用FANN库(环境部署)

    编译 安装和使用FANN库 环境部署 下载FANN的源代码 Github上面是官方的仓库 地址是libfann fann 它大概已经有两年时间是2 2 0版本 目前还看不到有什么活跃的提交 克隆主分支 git clone depth 1 h
  • 十个常见的Git面试题及详细解答

    Git是目前最流行的分布式版本控制系统之一 广泛应用于软件开发中 在Git面试中 面试官通常会提问一些与Git相关的问题 以评估候选人的版本控制技能和了解他们对Git的理解 本文将介绍十个常见的Git面试题 并提供详细的解答 帮助读者更好地
  • JVM 讲解

    目录 1 JVM 运行流程 2 JVM 基本组成 重要 2 1 堆 线程共享 2 2 Java 虚拟机栈 线程私有 2 3 本地方法栈 线程私有 2 4 程序计数器 线程私有 2 5 方法区 线程共享 3 OOM 4 JVM 垃圾回收算法
  • Airflow Trigger DAG with config

    1 rest api to trigger dag POST api experimental dags
  • 基于51单片机的霍尔自行车里程测速仪(含Keil程序和Proteus文件)

    系统概述 系统使用的模块有AT89C51单片机 LCD1602显示屏 霍尔测速模块 本设计采用51单片机为核心控制 使用LCD1602显示采集到的速度 霍尔测速模块进行测速 测速的原理是通过磁感应原理检测开关变化量 通过检测两个开关量的时间
  • 【javascript】闭包

    通过定时器从第一个元素开始往后 每隔一秒输出arr数组中的一个元素 但是运行过后 我们却会发现结果是每隔一秒输出一个 undefined 这是为什么呢 setTimeout 函数与for循环在调用时会产生两个独立执行上下文环境 当setTi
  • grep查找进程时,忽略grep进程本身

    ps ef grep 进程名 grep v grep grep v grep即去除结果中含有grep的进程 但是要注意如果你的进程名中本身含有grep也会被忽略 这时就需要更细致的规则 例如去除条件里加上一个空格 ps ef grep 进程
  • Matlab笔记

    1 创建矩阵 gt gt a 1 2 3 4 5 8 1 2 8 1 2 8可以是1起始值 公差 结束值 也可以是1 2 7 a 1 2 3 4 5 6 7 8 1 3 5 7 1 2 特殊矩阵 名称 函数 说明 单位矩阵 eye m n
  • leetcode链表刷题:删除中间节点

    题目如下所示 这道题正如评论区所言 最大的难度就是读懂题目本身 这道题的意思是 有一个链表 题目给了我这个链表上除了第一个和最后一个节点以外的一个中间节点 然后我要把这个中间节点给删掉 也就是说 我们能够进行操作的 是一个链表上的一个节点
  • leetcode 10. 正则表达式匹配

    2023 9 20 感觉是目前做过dp题里最难的一题了 本题首要的就是需要理解题意 翻了评论区我才发现之前一直理解的题意是错的 我原来理解的 匹配0次 是指 直接消失 不会影响到前面的字符 但是 和前一个字符其实是连体的 所以说 如果匹配0