【LeetCode热题100】打卡第6天:正则表达式匹配

news2025/1/10 17:02:33

文章目录

  • 正则表达式匹配
    • ⛅前言
    • 🔒题目
    • 🔑题解

正则表达式匹配

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页💖:知识汲取者的博客

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

Github地址📁:Chinafrfq · GitHub

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

🔒题目

原题链接:10. 正则表达式匹配 - 力扣(LeetCode)

在这里插入图片描述

🔑题解

  • 解法一:正则表达式

    这里标记是困难,但是如果使用正则表达式一行代码就解决了,但是这题的作者可能并不是想要我们使用正则表达式,而是使用动态规划,如果使用动态规划这题难度直接上升几个等级。所以大家不要为了做题而做题,而是去学习了解更多的算法思路,有时候我们不需要去把一个题给AC了,而是要做到,看到一个题能够第一时间直到这题考察的内容,应该使用哪种算法策略,毕竟现在AI这么流行,直接把一个题交给AI,他立马能够给你解答。

    当然这题使用正则也不赖,也是一种比较优秀的解法,但是却无法锻炼到我们的逻辑思维,因为太简单了🤣正则表达式YYDS

    import java.util.regex.Pattern;
    
    class Solution {
        public boolean isMatch(String s, String p) {
            return Pattern.matches(p, s);
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n),正则匹配本质是
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为字符串的长度

  • 解法二:动态规划

    本段代码来自这位大佬的:fomalhaut1998 - 力扣(LeetCode)

    class Solution {
        public boolean isMatch(String s, String p) {
            /*
            dp五部曲:
            设主串s的长度为m,设模式串p的长度为n;其中s只有小写字母,p有字母/./*
            1.状态定义:dp[i][j]为考虑s[0,i-1]与p[0,j-1]是否能匹配上,能匹配上就为true
            2.状态转移:若要求dp[i][j]就必须考虑到s[i-1]与p[j-1]
                2.1 当p[j-1]不是'*'时
                    2.1.1 若s[i-1]==p[j-1]时,即p[j-1]为'a'-'z'且与s[i-1]相等,看dp[i-1][j-1]
                    2.1.2 p[j-1] == '.'时,直接将'.'变成s[i-1],看dp[i-1][j-1]
                    注意:这里的'.'是匹配一个字符,而不是一连串,如"a.b"->"axb"
                2.2 当p[j-1]是'*'时,主要看p[j-2]做判断
                    2.2.1 p[j-2]为'a'-'z'并且p[j-2]==s[i-1],那么此时s继续往前看,p暂时不动
                        即:看dp[i-1][j]
                    2.2.2 p[j-2]为'.',那么".*"可以变为"....."可以匹配s[i-1]前面的任何字符(万能串)
                        因此,直接看dp[i-1][j](或者直接返回true)
                    2.2.3 剩下的就是p[j-2]为'a'-'z'且p[j-2]!=s[i-1],那么此时p的"x*"作废,看dp[i][j-2]
                这里:2.1.1与2.2.2可以看成一种情形:即s与p均前移一位
                    2.2.1与2.2.2可以看成一种情形:即p不动s前移一位
            3.初始化:
                3.1 空的s
                    3.1.1 空的p,空的s可以匹配空的p,因此dp[0][0]=true
                    3.1.2 非空的p,空的s可能可以匹配非空的p,例如"a*",因此需要经过转移计算
                3.2 空的p
                    3.2.1 空的s,同3.1.1
                    3.2.2 非空的s,空的p不可能匹配非空的s,因此dp[i][0]=false,i∈[1,m]
                3.3 非空的s与非空的p:需要经过转移计算
                其中:3.1.1与3.2.2可以合并为dp[i][0]=i==0
            4.遍历顺序:显然是正序遍历
            5.返回形式:返回dp[m][n]就是考虑s[0,m-1]与p[0,n-1]是否能匹配上
            */
            int m = s.length(), n = p.length();
            boolean[][] dp = new boolean[m + 1][n + 1];
            // 初始化dp[i][0]
            // for(int i = 0; i <= m; i++) {
            //     dp[i][0] = i == 0;
            // }
            dp[0][0] = true;
            // i从0开始
            for(int i = 0; i <= m; i++) {
                // 注意j从1开始
                for(int j = 1; j <= n; j++) {
                    if(p.charAt(j - 1) != '*') {
                        // 1.当p[j-1]不是'*'时(注意j已经从1开始了)
                        // 这里要注意运算优先级问题(加括号)
                        if(i >= 1 && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.')) {
                            // s与p均前移一位
                            dp[i][j] = dp[i - 1][j - 1];
                        }
                    } else {
                        // 2.当p[j-1]是'*'时,主要看p[j-2]做判断
                        if(j >= 2 && i >= 1 && 
                        (p.charAt(j - 2) == s.charAt(i - 1) || p.charAt(j - 2) == '.')) {
                            // 看"x*":p不动s前移一位
                            dp[i][j] = dp[i - 1][j];
                        }
                        // 不看"x*":
                        // 剩下的为p[j-2]为'a'-'z'且p[j-2]!=s[i-1],那么此时p的"x*"作废,看dp[i][j-2]
                        if(j >= 2) {
                            dp[i][j] |= dp[i][j - 2];
                        }
                        // 这里的|=表示只要满足了其中一个条件就可以使得dp[i][j]==true
                        // 通俗一点的解释就是:当p[j-1]=='*'时,
                        // 若p[j-2]==s[i-1]||p[j-2]=='.',则dp[i][j]可以继承dp[i-1][j]:转移路径1
                        // 若p[j-2]!=s[i-1],则dp[i][j]可以继承dp[i][j-2]:转移路径2
                        // 满足任意一条转移路径就可以使得dp[i][j]=true
                    }        
                }
            }
            // 所求即为考虑s[0,m-1]与p[0,n-1]是否能匹配上
            return dp[m][n];
        }
    }
    

    详情参考官方代码

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ) O(n*m) O(nm)
    • 空间复杂度: O ( n ∗ m ) O(n*m) O(nm)

    其中 n n n 为数组中元素的个数

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

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

相关文章

从原理总结chatGPT的Prompt的方法

一 什么是chatGPT chatGPT全称是Generative Pre-trained Transformer&#xff0c;它是一种专注于对话生成的语言模型&#xff0c;可以根据用户的文本输入&#xff0c;做出相应的智能回答。chatGPT是由OpenAI于2018年研发的语言模型&#xff0c;其中OpenAI是于2015年由特斯拉的…

Postman新手教程

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 目录 文章目录 一、Postman背景介绍 二、Postman下载地址 三、Postman简单使用 一、Postman背景介绍 Postman是Chrome插件类产品中的代表产品之一&#xff0c;这款网页调试工具不仅可以调…

位图布隆过滤器

位图 概念&#xff1a;就是用每一位来存放某种状态&#xff0c;适用于海量数据&#xff0c;数据无重复的场景。通常是用来判断某个数据存不存在的。 比如&#xff0c;需要在40亿个整数中&#xff0c;查看某个数是否存在&#xff1f; 1G1024M*1024KB*1024B~10亿字节~80亿比特。…

k8s实战篇1-用minikube发布服务hello-minikube

1 安装minikube curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 sudo install minikube-darwin-amd64 /usr/local/bin/minikube 2 Install kubectl binary with curl on macOS 1 Download the latest release: curl -LO "h…

Eclipse Ⅶ

哈喽各位&#xff0c;今天继续分享第七部分的内容&#xff0c;喜欢可以点赞和收藏&#xff0c;这是我的动力来源hahahhah&#xff01; 今天谈谈Eclipse 生成 jar 包、Eclipse 关闭项目以及Eclipse 编译项目。 废话不多说&#xff0c;开始咯&#xff01; Eclipse 生成 jar 包…

Linux常见指令-2

我们本期继续学习Linux基本指令&#xff0c;没有看过第一期的小伙伴建议先看第一期 (4条消息) Linux常见指令-1_KLZUQ的博客-CSDN博客 目录 15.时间相关指令 16.cal指令 17.find指令 18.grep指令 19.zip/unzip指令 20.tar指令 21.bc指令 22.uname –r指令 22.重要的几…

PMP考试总结-2023-05-27

目录 前言 为什么会参加PMP考试&#xff1f; 那么什么是PMP&#xff1f; Plan 目标&#xff1a; 方式方法&#xff1a; 达标标准&#xff1a; Do 执行内容&#xff1a; Check 执行效果 计划的复盘 一、考试前及当天的计划&#xff1a; 二、整个备考计划&#xff…

如何正确地使用ES6提高我们的代码质量

前言 相信每个前端工程师&#xff0c;或者了解前端的人都知道ES6。它是js的一次巨变&#xff0c;它为我们开发js前端项目的时候带来了许多更好的去书写代码的方式。但是很多时候我们可能都没有过度地去关注优化代码这一块内容&#xff0c;哪怕有也只是注意到了一些比较大众化&…

Linux进程概念引入

文章目录 冯诺依曼体系操作系统概念设计目的定位系统调用和库函数的概念 进程概念描述进程PCBtask_struct内容分类 组织进程查看进程通过系统调用获取进程标识符通过系统调用创建进程 冯诺依曼体系 目前我们的计算机基本都是遵守冯诺依曼体系的&#xff0c;在冯诺依曼体系中&am…

[Kubernetes] - RabbitMQ学习

1.消息队列 消息&#xff1a; 在应用间传送的数据队列&#xff0c;先进先出 1.2. 作用 好处&#xff1a;解耦&#xff0c; 容错&#xff0c;削峰坏处&#xff1a;降低系统可用性&#xff0c;系统复杂度提高&#xff0c;一致性问题&#xff1b; RabbitMQ组成部分&#xff1a…

云上高校导航 导入 与 配置教程

开通 云开发 功能&#xff08;首月免费&#xff0c;次月19.9&#xff09;&#xff0c;激活 云数据库、云存储和云函数 功能。 将 项目 文件夹下 最新版本的 文件夹下的 Cloud-based_University_Navigation 整个文件夹 复制到项目路径下&#xff08;比如 D:\WeChatProjects&…

Zabbix Server Api批量添加Zabbix Agent

脚本或使用自动化工具来批量添加Zabbix Agent&#xff0c;从而减少手动操作和提高效率 使用API添加主机可以减少人为错误的发生。通过自动化和脚本&#xff0c;可以确保正确的配置被应用到每个主机上&#xff0c;避免了手动操作可能导致的配置错误。 使用前提条件 1、zabbix…

C919用了哪些人工智能(AI)技术?

#国产大飞机C919商业首飞#近日&#xff0c;C919在国人的期盼下终于迎来了首次商飞&#xff0c;机票已公开售卖。众所周知&#xff0c;C919是一款全新的、先进的大飞机&#xff0c;那你知道它采用了哪些新的人工智能&#xff08;AI&#xff09;技术吗&#xff1f;下面让我来为大…

[golang 微服务] 2. RPC架构介绍以及通过RPC实现微服务

一.简介 在上一节简单了解了微服务定义和优缺点之后&#xff0c;在使用微服务框架之前&#xff0c;需要首先了解一下RPC架构,通过RPC可以更形象了解微服务的工作流程 RPC的概念 RPC(Remote Procedure Call Protocol)&#xff0c;是 远程过程调用的缩写&#xff0c;通俗的说就是…

【提示学习】HPT: Hierarchy-aware Prompt Tuning for Hierarchical Text Classification

论文信息 名称内容论文标题HPT: Hierarchy-aware Prompt Tuning for Hierarchical Text Classification论文地址https://arxiv.org/abs/2204.13413研究领域NLP, 文本分类, 提示学习, 层级标签文本分类提出模型HPT(Hierarchy-aware Prompt Tuning)来源EMNLP 2022源码https://gi…

SpringBoot AOP切面编程 使用案例

参考资料 Springboot AOP实现指定敏感字段数据加密 &#xff08;数据加密篇 二&#xff09;【SpringBoot-3】切面AOP实现权限校验&#xff1a;实例演示与注解全解【小家Spring】Spring AOP中Pointcut切入点表达式最全面使用介绍AOP编程过程中的Signature接口 本篇文章核心思想…

(详解)vue中实现主题切换的三种方式

目录 一、背景 二、实现思路 方法1&#xff1a;定义全局的CSS变量 方法2&#xff1a;切换已定义好的css文件 方法3&#xff1a;切换顶级CSS类名 (需使用css处理器,如sass、less等) 一、背景 在我们开发中我们会遇到像是需要切换程序风格、主题切换啦这种应用场景。 参考大佬…

经典智能合约案例之发红包

经典智能合约案例&#xff1a;发红包 角色分析&#xff1a;发红包的人和抢红包的人 功能分析&#xff1a; 发红包&#xff1a;发红包的功能&#xff0c;可以借助构造函数实现&#xff0c;核心是将ether打入合约&#xff1b; 抢红包&#xff1a;抢红包的功能&#xff0c;抢成…

Flume系列:案例-Flume 聚合拓扑(常见的日志收集结构)

目录 Apache Hadoop生态-目录汇总-持续更新 1&#xff1a;案例需求-实现聚合拓扑结构 3&#xff1a;实现步骤&#xff1a; 2.1&#xff1a;实现flume1.conf - sink端口4141 2.2&#xff1a;实现flume2.conf- sink端口4141 2.3&#xff1a;实现flume3.conf - 监听端口4141 …

32 KVM管理系统资源-管理虚拟内存热插

文章目录 32 KVM管理系统资源-管理虚拟内存热插32.1 概述32.2 约束限制32.3 操作步骤32.3.1 配置虚拟机XML32.3.2 热插并上线内存 32 KVM管理系统资源-管理虚拟内存热插 32.1 概述 在虚拟化场景下&#xff0c;虚拟机的内存、CPU、外部设备都是软件模拟呈现的&#xff0c;因此…