leetcode 10. 正则表达式匹配

2023-09-20 11:17:58

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()];
    }
};

        

更多推荐

基于Python的海量豆瓣电影、数据获取、数据预处理、数据分析、可视化、大屏设计项目(含数据库)

目录项目介绍研究背景国内外研究现状分析研究目的研究意义研究总体设计网络爬虫介绍豆瓣电影数据的采集数据预处理大数据分析及可视化豆瓣影评结构化分析大屏可视化文本可视化总结每文一语项目介绍有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主!!!!!!!!!!本文基于Python的网络爬虫手段对豆瓣电影网站进行数据

Javascript数据类型和类型转换的应用场景

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录基础数据类型和引用数据类型使用typeof操作符包装类型隐式类型转换1.数字转字符串:2.字符串转数字:3.布尔值转数字:4.字符串转布尔值:5.对象的隐式转换显式类型转换类型转换规则1.类型转换的优先级:在J

Python 之plt.plot()的介绍以及使用

文章目录介绍代码实例介绍plt.plot()是Matplotlib库中用于绘制线图(折线图)的主要函数之一。它的作用是将一组数据点连接起来,以可视化数据的趋势、关系或模式。以下是plt.plot()的详细介绍:plt.plot(x,y,fmt,**kwargs)x:表示X轴上的数据点,通常是一个列表、数组或一维序列,用

使用ZoeDepth生成深度估计图

目前单目深度估计分为两个派系,metricdepthestimation(度量深度估计,也称绝对深度估计)和relativedepthestimation(相对深度估计)。ZoeDepth是第一个结合相对和绝对深度的多模态单目深度估计网络。本博文仅记录使用ZoeDepth生成深度估计图的过程(因为直接按项目说明中进行使

【Azure】浅析 Azure 交互工具:Azure 门户、Azure Cloud Shell、 Azure CLI 和 Azure PowerShell | 文末送书

文章目录前言Azure门户AzureCloudShell,包括AzureCLI和AzurePowerShell什么是AzureCloudShell?什么是AzurePowerShell?什么是AzureCLI?对Azure交互的工具在AZ-900中的考点文末送书书籍介绍关于作者获取方式前言本文将深入浅出地探讨Micro

k8s(Kubernetes)集群部署--使用 kubeadm方式部署

k8s集群部署--使用kubeadm方式部署一、测试所需环境(三台均要执行)二、配置准备(三台均要执行)1.重命名hostname、添加hosts2.关闭防火墙、selinux与swap3.添加网桥过滤及内核转发配置文件4.同步时间5.安装ipset及ipvsadm三、安装docker(三台均要执行)1.配置Docke

微服务 第三章 Spring Cloud 简介

系列文章目录第一章Java线程池技术应用第二章CountDownLatch和Semaphone的应用第三章SpringCloud简介文章目录系列文章目录@[TOC](文章目录)前言:SpringCloud是一款基于SpringBoot实现的微服务框架1、SpringCloud的常用组件如下表所示。2、SpringBoo

Ubuntu20.04安装Nvidia显卡驱动、CUDA11.3、CUDNN、TensorRT、Anaconda、ROS/ROS2

1.更换国内源打开终端,输入指令:wgethttp://fishros.com/install-Ofishros&&.fishros选择【5】更换系统源,后面还有一个要输入的选项,选择【0】退出,就会自动换源。2.安装NVIDIA驱动这一步最痛心了家人们,网上的教程太多了,我总是想着离线安装,每次安装都无法开机,要不就

【Android】关于Activity的onSaveInstanceState生命周期

最近笔者求职时面试一家大厂,被问到Activity的生命周期,其中面试官着重问了onSaveInstanceState的调用是在onStop之前还是之后,本人当时有点蒙圈,之前也没有关注它到底是在OnStop之前还是之后。但是这个方法在什么时候调用的重要吗?我们只是用它来保存数据的,然后在onRestoreInstan

Learn Prompt-经验法则

还记得我们在“基础用法”当中提到的三个经验法则吗?尝试提示的多种表述以获得最佳结果使用清晰简短的提示,避免不必要的词语减少不精确的描述现在经过了几页的学习,我认为是时候引入一些新的原则了。3.一个话题对应一个chat​ChatGPT是一个聊天机器人,在生成过程中,它会参考以前的聊天历史,同一对话中出现不同主题会影响下游

ChatGPT Prompting开发实战(九)

一、什么是推理式的prompt开发有时候需要针对一些产品的评论文本进行分析,常见的做法如对每段评论所表达的情感倾向进行推理判断,识别用户对这个产品的使用体验是否满意,那么可以编写相关的prompt来做这样的推理分析。另外,针对不同的文本内容,也可以根据给出的主题来让模型判断一段内容属于什么样的主题。接下来会给出具体示例

热文推荐