每日OJ题_两个数组dp④_力扣44. 通配符匹配

目录

力扣44. 通配符匹配

解析代码


力扣44. 通配符匹配

44. 通配符匹配

难度 困难

给你一个输入字符串 (s) 和一个字符模式 (p) ,请你实现一个支持 '?' 和 '*' 匹配规则的通配符匹配:

  • '?' 可以匹配任何单个字符。
  • '*' 可以匹配任意字符序列(包括空字符序列)。

判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。

示例 1:

输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:s = "aa", p = "*"
输出:true
解释:'*' 可以匹配任意字符串。

示例 3:

输入:s = "cb", p = "?a"
输出:false
解释:'?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。

提示:

  • 0 <= s.length, p.length <= 2000
  • s 仅由小写英文字母组成
  • p 仅由小写英文字母、'?' 或 '*' 组成
class Solution {
public:
    bool isMatch(string s, string p) {

    }
};

解析代码

状态表示:

对于两个字符串之间的 dp 问题,我们一般的思考方式如下:

        选取第⼀个字符串的 [0, i] 区间以及第⼆个字符串的 [0, j] 区间当成研究对象,结合题目的要求来定义状态表示。然后根据两个区间上最后一个位置的字符,来进行分类讨论,从而确定状态转移方程。

dp[i][j] 表示: p 字符串 [0, j] 区间内的子串能否匹配字符串 s 的 [0, i] 区间内的子串。


状态转移方程:

根据最后一个位置的元素,结合题目要求,分情况讨论:

  • 当 s[i] == p[j] 或 p[j] == '?的时候,此时两个字符串匹配上了当前的一个字符,只能从 dp[i - 1][j - 1] 中看当前字符前面的两个子串是否匹配。只能继承上个状态中的匹配结果, dp[i][j] = dp[i - 1[j - 1] ;
  • 当 p[j] == '*' 的时候,此时匹配策略有两种选择:
  1. 一种选择是: * 匹配空字符串,直接继承状态 dp[i][j - 1] ,此时 dp[i][j] = dp[i][j - 1] ;
  2. 另一种选择是: * 向前匹配 1 ~ n 个字符,直至匹配上整个 s 串。此时相当于从 dp[k][j - 1] (0 <= k <= i) 中所有匹配情况中,选择性继承可以成功的情况。此时 dp[i][j] = dp[k][j - 1] (0 <= k <= i) ;
  • 当 p[j] 不是特殊字符,且不与 s[i] 相等时,无法匹配,p[i][j] = flase

三种情况加起来,就是所有可能的匹配结果。综上所述,状态转移方程为:

  • 当 s[i] == p[j] 或 p[j] == '?' 时: dp[i][j] = dp[i][j - 1] ;
  • 当 p[j] == '*' 时,有多种情况需要讨论: dp[i][j] = dp[k][j - 1] (0 <=k <= i) ;

这个状态转移方程时间复杂度为O(N^3),要想想优化。


        优化:当发现计算一个状态的时候,需要一个循环才能搞定的时候,我们要想到去优化。优化的方向就是用一个或者两个状态来表示这一堆的状态。通常就是把它写下来,然后用数学的方式做一下等价替换:

当 p[j] == '*' 时,状态转移方程为:dp[i][j] = dp[i][j - 1] || dp[i - 1][j - 1] || dp[i - 2][j - 1]......

        发现 i 是有规律的减小的,因此我们去看看 dp[i - 1][j] ,列出 dp[i - 1][j] = dp[i - 1][j - 1] || dp[i - 2][j - 1] || dp[i - 3][j - 1] ......

        然后就能发现, dp[i][j] 的状态转移方程里面除了第一项以外,其余的都可以用dp[i -1][j] 替代。因此优化我们的状态转移方程为: dp[i][j] = dp[i][j - 1] || dp[i - 1][j]。


初始化、填表顺序、返回值:

初始化:空串是有研究意义的,因此我们将原始 dp 表的规模多加上一行和一列,表示空串。由于 dp 数组的值设置为是否匹配,为了不与答案值混淆,我们需要将整个数组初始化为false 。由于需要用到前一行和前一列的状态,初始化第一行、第一列即可。

dp[0][0] 表示两个空串能否匹配,答案是显然的, 初始化为 true 。

第一行表示 s 是一个空串, p 串和空串只有一种匹配可能,即 p 串表示为 "***" ,此时也相当于空串匹配上空串。所以,我们可以遍历 p 串,把所有前导为 "*" 的 p 子串和空串的 dp 值设为 true 。

第一列表示 p 是一个空串,不可能匹配上 s 串,跟随数组初始化成false即可。

填表顺序:从上往下填写每一行,每一行从左往右,最后返回dp[m][n]。

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size(), n = p.size();
        s = " " + s, p = " " + p;
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
        // dp[i][j] 表示: p字符串[0, j]区间内的子串能否匹配字符串s的[0, i]区间内的子串
        dp[0][0] = true;
        for(int j = 1; j <= n; ++j)
        {
            if(p[j] == '*')
                dp[0][j] = true;
            else
                break;
        }

        for(int i = 1; i <= m; ++i)
        {
            for(int j = 1; j <= n; ++j)
            {
                if(s[i] == p[j] || p[j] == '?')
                    dp[i][j] = dp[i - 1][j - 1];
                else if(p[j] == '*')
                    dp[i][j] = (dp[i][j - 1] || dp[i - 1][j]);
            }
        }
        return dp[m][n];
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如果用大模型考公,kimi、通义千问谁能考高分?

都说大模型要超越人类了&#xff0c;今天就试试让kimi和通义千问做公务员考试题目&#xff0c;谁能考高分&#xff1f; 测评结果再次让人震惊&#xff01; 问题提干&#xff1a;大小两种规格的盒装鸡蛋&#xff0c;大盒装23个&#xff0c;小盒装16个&#xff0c;采购员小王买了…

【Java集合】面试题汇总

Java 集合Java 集合概览1. List, Set, Queue, Map 四者的区别&#xff1f;2. ArrayList 和 Array&#xff08;数组&#xff09;的区别&#xff1f;3. ArrayList 和 Vector 的区别?4. Vector 和 Stack 的区别?&#xff08;了解即可&#xff09;5. ArrayList 可以添加 null 值吗…

ts中的类型简介

注意&#xff1a;尽量不要在ts中用var&#xff0c;不然后续维护代码&#xff0c;容易出现很多问题。 var定义会在全局中生效&#xff0c;而let只会在作用域中起作用。 boolean string number array tuple&#xff08;元组&#xff09; enum&#xff08;枚举&#xff09; null u…

自动驾驶中的传感器融合算法:卡尔曼滤波器和扩展卡尔曼滤波器

自动驾驶中的传感器融合算法&#xff1a;卡尔曼滤波器和扩展卡尔曼滤波器 附赠自动驾驶学习资料和量产经验&#xff1a;链接 介绍&#xff1a; 追踪静止和移动的目标是自动驾驶技术领域最为需要的核心技术之一。来源于多种传感器的信号&#xff0c;包括摄像头&#xff0c;雷达…

想进阶为 Go 语言高级开发工程师吗?那么,一定要阅读此文!

大家好&#xff0c;我是孔令飞&#xff0c;字节跳动云原生开发专家、前腾讯云原生技术专家&#xff1b;《企业级Go项目开发实战》作者&#xff0c;云原生实战营 知识星球星主&#xff1b; 我们知道&#xff0c;Go 出自名门 Google 公司&#xff0c;是一门支持并发、垃圾回收的编…

绝地求生:齐贺PUBG七周年!分享你的游玩感受及反馈赢惊喜道具

PUBG七周年庆典火热进行中&#xff0c;特殊道具、周年主题艾伦格上线&#xff01;七周年期间游玩PUBG&#xff0c;在评论区分享你的游玩感受及反馈&#xff0c;即可参与活动赢取夏日浪潮宝箱奖励。 参与方式 齐贺PUBG七周年&#xff01;在评论区分享分享你的七周年游玩感受及反…

(学习日记)2024.04.09:UCOSIII第三十七节:事件函数接口

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

stable diffusion的从安装到使用

stable-diffusion&#xff0c;一个免费开源的文生图软件&#xff0c;文章主要讲怎么从源码开始安装&#xff0c;以及使用的方式 git地址&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui 本人电脑环境win10&#xff0c;软件pycharm&#xff0c;需要提前…

基于直方图的图像曝光量分析FPGA实现,包含tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 正常图像&#xff1a; checkb位于f192b和f250b之间 多度曝光图像&#xff1a; checkb位于f192b和f250b之外&#xff0c;判决为曝光过度。 2.算法…

k8s_入门_kubelet安装

安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…

【神经网络】卷积神经网络CNN

卷积神经网络 欢迎访问Blog全部目录&#xff01; 文章目录 卷积神经网络1. 神经网络概览2.CNN&#xff08;Convolutional Neunal Network&#xff09;2.1.学习链接2.2.CNN结构2.2.1.基本结构2.2.1.1输入层2.2.1.2.卷积层|Convolution Layers2.2.1.3.池化层|Pooling layers2.3…

设计模式——2_8 策略(Strategy)

文章目录 定义图纸一个例子&#xff1a;如何切换坦克的攻击方式GameElement&#xff08;游戏元素&#xff09;TankFactory&#xff08;坦克工厂&#xff09;Tank&#xff08;坦克&#xff09; 医疗车和飞行车策略模式Behavior(行为)TankTankFactory 碎碎念策略和状态为什么我们…

[数据结构]双向带头循环链表制作

前面我们有提到&#xff0c;单向不带头循环链表的制作 这里我们介绍一个双向带头循环链表的制作方法 双向带头循环链表的示意图如下 带头指针的作用体现在哪呢? 第一、防止头节点为空,既有头结点&#xff0c;头指针始终指向头结点&#xff0c;那么无论链表是否为空&#xf…

游戏公司面试题系列-CocosCreator实现虚拟摇杆控制角色移动中心旋转自转小球割草旋转逻辑

游戏公司面试题系列-CocosCreator实现虚拟摇杆控制角色移动&中心旋转自转小球&割草旋转逻辑<&#xff01;&#xff01;&#xff01;文章末尾有完整代码下载链接地址&#xff01;&#xff01;&#xff01;> Hello大家好&#xff01;今天我们来用最新的CocosCreat…

pringboot2集成swagger2出现guava的FluentIterable方法不存在

错误信息 Description: An attempt was made to call a method that does not exist. The attempt was made from the following location: springfox.documentation.spring.web.scanners.ApiListingScanner.scan(ApiListingScanner.java:117) The following method did not ex…

PHP运算符与流程控制

华子目录 运算符赋值运算符算术运算符比较运算符逻辑运算符连接运算符错误抑制符三目运算符自操作运算符 计算机码位运算符 运算符优先级流程控制控制分类顺序结构分支结构if分支switch分支 循环结构for循环while循环continuebreak 运算符 运算符&#xff1a;operator&#xf…

谷歌留痕霸屏要怎么做?

谷歌留痕霸屏&#xff0c;就是让你的网站或者页面在谷歌搜索结果里尽可能多地出现&#xff0c;就像是在你的潜在客户眼前留下深刻印象一样&#xff0c;你要做的就是在一些高权重平台发布有价值的信息&#xff0c;同时巧妙地留下你的品牌名、产品名或者任何你想要推广的关键词&a…

谷歌不收录怎么办?

谷歌不收录首先你要确认自己网站有没有出问题&#xff0c;比如你的网站是否已经公开&#xff0c;rboot是否允许搜索引擎进来&#xff0c;网站架构有没有问题&#xff0c;面包屑的结构是否有问题&#xff0c;确保你的网站没问题 接下来就是优化这个过程&#xff0c;有内容&#…

python|drop的应用

drop 删除列B 删除索引为1的行 删除列为‘A’&#xff0c;‘C’的列&#xff0c;axis表示方向 删除时保留原始 DataFrame&#xff08;使用 inplaceFalse&#xff09; 删除时直接修改原始 DataFrame&#xff08;使用 inplaceTrue&#xff09;

SEO优化艺术:精细化技巧揭示与搜索引擎推广全面战略解读

SEO&#xff08;搜索引擎优化&#xff0c;Search Engine Optimization&#xff09;是一种网络营销策略&#xff0c;旨在通过改进网站内外的各项元素&#xff0c;提升网站在搜索引擎自然搜索结果中的排名&#xff0c;从而吸引更多目标用户访问网站&#xff0c;增加流量&#xff…