[LeetCode - 动态规划] 10. Regular Expression Matching

leetcode10_Regular Expression Matching[附动态规划] .问题描述 Implement regular expression matching with support for '.and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the ent 阅读详情

1 问题

Implement regular expression matching with support for ‘.’ and ‘*’.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

2 分析

2.1 该问题的递归性

如果不考虑".""*", 检查两个字符串是否匹配的方法是逐位比较,如果这两个字符串有一个位置上的字符不相等,那么这两个字符串不匹配,如果两个字符串所有位置均对应相等,那么这两个字符串匹配。
接下来考虑存在".""*"的情况:

  • "."匹配任意一个字符,如果待比较的两个字符串某一位置上的字符是".", 则认为这两个位置上的字符相等,继续下一个位置的比较。
  • "*"可以匹配0个或者多个紧邻的前一个字符。即"*"的存在使该字符串变成了多个可能的字符串。因此,必须将"*"能够表示的所有情况与另外一个字符串相比较,如果存在一种匹配的情况,那么这两个字符串匹配,反之,这两个字符串不匹配。
    • "*"存在时,"*"和其紧邻的前一个字符(设为m)有如下三种可能的匹配情况:
    • 空字符串”“
    • 单一字符m
    • 多个字符mm...

在对"*"表示的所有可能情况,进行搜索、确定是否匹配的过程中,如果一种情况匹配失败,就要回溯,选择下一种可能情况来进行操作。因此,该问题具有递归性。

2.2 递归解法

递归,回溯解决该问题的伪代码如下:

isMatch(String s, String p):

  • base case:
    • if p == "": //对应情况:模式字符串匹配完毕
      • if s == "": return true
      • else: return false
    • if s == "": //对应情况:源字符串匹配完毕,模式字符串有剩余
      • if p的长度大于1,且p的第二个字符是*: return isMatch(s,p[2:end])
      • else: return false
  • 递归过程:
    • if p的长度大于1 且 p[1] == "*"://对应情况:str*的匹配
      • if s[0] == p[0] or p[0] == ".":
        • if isMatch(s[1:end],p[2:end]): return true//对应情况:将str*视为单个字符
        • if isMatch(s[1:end], p): return true; //对应情况:将str*视为多个字符
      • if isMatch(s,p[2, end]): return true;//对应情况:将str*视为空
      • return false
    • else if s[0] == p[0] or p[0] == ".":
      • return isMatch(s[1:end], p[1:end])
    • else: return false

匹配字符串str*至少会存在3种子问题,因此, 算法的时间复杂度与模式字符串中"*"的个数有关系,设其为 n ,则递归算法的时间复杂度是O(3n)

2.3 使用动态规划优化代码

  1. 2.1-2.2节分析得出该问题具有递归性,可以分解为多个子问题求解。下面证明:该问题的子问题是重叠的。
    "a*b*c为例:
    重叠子问题
    上图中虚线方框内的子问题在递归过程中被重复求解,因此子问题是重叠的。
  2. 该问题具有最优子结构,如果sp整个字符串匹配,那么它们任何一个对应子字符串匹配。

通过上述分析,可以得出结论: 动态规划可以用于优化代码。
dp[i][j]表示s[0:i],p[0,j]是否匹配。 dp[i][j]可以通过2.2节中分析的子问题关系逐步计算出来,计算方法为:

 If p.charAt(j) == s.charAt(i) :  dp[i][j] = dp[i-1][j-1];
 If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
 If p.charAt(j) == '*':
     if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2]  
     if p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
                              dp[i][j] = dp[i-1][j]
                           or dp[i][j] = dp[i][j-1]
                           or dp[i][j] = dp[i][j-2]

经过动态规划优化后算法的时间复杂度为 O(mn) , 其中 m,n 分别表示s,p的长度。

3 代码

3.1 递归解法:

public class Solution {
    public boolean isMatch(String s, String p) {
        System.out.println("S: "+s + " P: " + p);
        //base case
        if(p.length() == 0){
            if(s.length() == 0){
                return true;
            }else{
                return false;
            }
        }

        if(s.length() == 0){
            if(p.length() > 1 && p.charAt(1) == '*'){
                return isMatch(s, p.substring(2));
            }else{
                System.out.println(s+" "+p);
                return false;
            }
        }
        //recursive procedure
        if(p.length() > 1 && p.charAt(1) == '*'){
            if( s.charAt(0) == p.charAt(0) || p.charAt(0) == '.'){
                if(isMatch(s.substring(1), p.substring(2))){
                    return true;
                }
                if(isMatch(s.substring(1), p)){
                    return true;
                }
            }
            if(isMatch(s, p.substring(2))){
                return true;
            }
            return false;
        }else if(s.charAt(0) == p.charAt(0) || p.charAt(0) == '.'){
            return isMatch(s.substring(1), p.substring(1));
        }else{
            return false;
        }
    }
}

3.2 dp解法

public class Solution {
    public boolean isMatch(String s, String p) {    
    if (s == null || p == null) {
        return false;
    }
    boolean[][] dp = new boolean[s.length()+1][p.length()+1];
    dp[0][0] = true;
    for (int i = 0; i < p.length(); i++) {
        if (p.charAt(i) == '*' && dp[0][i-1]) {
            dp[0][i+1] = true;
        }
    }
    for (int i = 0 ; i < s.length(); i++) {
        for (int j = 0; j < p.length(); j++) {
            if (p.charAt(j) == '.') {
                dp[i+1][j+1] = dp[i][j];
            }
            if (p.charAt(j) == s.charAt(i)) {
                dp[i+1][j+1] = dp[i][j];
            }
            if (p.charAt(j) == '*') {
                if (p.charAt(j-1) != s.charAt(i) && p.charAt(j-1) != '.') {
                    dp[i+1][j+1] = dp[i+1][j-1];
                } else {
                    dp[i+1][j+1] = (dp[i+1][j] || dp[i][j+1] || dp[i+1][j-1]);
                }
            }
        }
    }
    return dp[s.length()][p.length()];
}

[1] dp解法的代码来源于 https://discuss.leetcode.com/topic/40371/easy-dp-java-solution-with-detailed-explanation

FPGA实现电机转速PID控制 通过纯RTL实现电机转速PID控制,包括电机编码器值读取,电机速度、正反转控制,PID算法,卡尔曼滤波,最终实现对电机速度进行控制,使其能够渐近设定的编码器目标值。 阅读详情

相关推荐

动态SLAM中的YOLO与ORB-SLAM3融合:实时目标检测与动态点云滤除实战

本文介绍了如何结合YOLOv5目标检测与ORB-SLAM3视觉SLAM系统,实现动态环境下的目标检测与视觉SLAM任务。文章详细阐述了从源码下载、依赖安装(包括libtorch配置)、编译运行步骤(包括ROS环境和非ROS环境下的编译方法),到RGBD-TUM数据集准备与关联处理的全流程。同时针对常见错误提供了解决方案,如libtorch路径配置、ROS环境冲突等。最后展示了系统运行方法,并探讨了未来可能的优化方向,包括增强目标检测能力和改进动态环境下的地图构建。该集成系统为机器人智能导航和环境感知提供了有

LXY_LOVE36的博客 207

题解:Regular Expression Matching

题目: Implement regular expression matching with support for '.and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire

WaverDn的博客 400

STM32F103单片机HAL库例程-VS1053音乐MP3播放器(SD卡+vs1053+FATFS文件系统).rar

1、嵌入式物联网单片机项目开发实战。例程经过精心编写,简单好用。2、代码使用KEIL HAL库开发,当前在STM32F103运行,如果是STM32F103其他型号芯片,依然适用,请自行更改KEIL芯片型号以及FLASH容量即可。3、软件下载时,请注意keil选择项是jlink还是stlink。4、技术v:349014857;5、如果接入其他传感器,请查看发布的其他资料。6、单片机与模块的接线,在代码当中均有定义,请自行对照。7、若硬件差异,请根据自身情况适当调整代码,程序仅供参考。8、代码有注释说明,请耐心阅读。

Leetcode: Regular Expression Matching

Implement regular expression matching with support for '.and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input st

ZkvIA的博客 2万+

[Leetcode] 10. Regular Expression Matching

题目 Implement regular expression matching with support for.and*..’ Matches any single character.*’ Matches zero or more of the preceding element. The matching should cover the

neilooo的博客 468

每日算法之九:Regular Expression Matching

Implement regular expression matching with support for '.and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input

yapian8的专栏 857

Regular Expression Matching问题及解法

问题描述: Implement regular expression matching with support for '.and '*'. 示例: '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the e

刘天的博客 552

LeetCode10. Regular Expression Matching动态规划&递归】

       对于p字符串有点、字母、点*、字母*四种元素,点匹配任意一个字母,字母匹配相同的一个字母,点*匹配任意字母(可以是任意不同字母,例如.*匹配abc),字母*匹配连续任意个相同字母,值得注意的是*的任意包括0个。由于*可以匹配任意个,造成检验s和p是否完全匹配的时候难以确定究竟*匹配几个字母合适,这正是本题的关键点。题意简单粗暴,看一下原题,然后分析一下如何处理。 Given an...

zhaoqinmuxue的博客 1856

动态规划 LeetCode 10 Regular Expression Matching

动态规划 LeetCode 10 Regular Expression Matching

xiaobaoo的博客 194

leetcode 10. Regular Expression Matching动态规划

题目 Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding el...

scqlovezy的博客 275

LeetCode】解题10Regular Expression Matching动态规划解法)

LeetCode解题 10Regular Expression Matching动态规划解法)Problem 10: Regular Expression Matching [Hard]解题思路Solution (Java) Problem 10: Regular Expression Matching [Hard] Given an input string (s) and a patter...

Fayedily的博客 411

leetcode10 Regular Expression Matching 使用动态规划DP 代码详解

题目:                                      大致意思是实现一个两个字串的正则匹配,'.'可以代表任何字母,‘*’表示它之前的字母重复0到多次。 例如 a*可以是aaa或者是a或者为空等等。   实现代码: class Solution { public boolean isMatch(String s, String p) { i...

Lin_QC的博客 1137

LeetCode 10 - Regular Expression Matching 动态规划总结 (DP)

动态规划个人总结

此CSDN账号下原创文章未经本人许可,不得用于商业用途。转载请注明出处,否则保留追究法律责任的权利。 300

LeetCode 10. Regular Expression Matching (动态规划) C++

Given an input string (s) and a pattern §, implement regular expression matching with support for.and*. 给定输入字符串和模式(p),实现支持“ . ”和“ * ”的正则表达式匹配。 '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching shoul

ganlanA的博客 403

LeetCode 10. Regular Expression Matching python特性、动态规划、递归

前言 本文主要提供三种不同的解法,分别是利用python的特性、动态规划、递归方法解决这个问题 使用python正则属性 import re class Solution2: # @return a boolean def isMatch(self, s, p): return re.match('^' + p + '$', s) != None ...

楼上小宇_home 7075

算法|动态规划|leetcode10. Regular Expression Matching

leetcode10. Regular Expression Matching There are three special combination ‘.’ ‘.*’ ‘b*’, (b means a specific letter) Pseudo-Code //Build up a M.LEN*N.LEN matrix dp, where M is the matching strin...

博客 181

Leetcode 10. Regular Expression Matching Python3 递归与动态规划

.问题描述 Given an input string (s) and a pattern (p), implement regular expression matching with support for'.'and'*'where: '.'Matches any single character.​​​​ '*'Matches zero or more of the preceding element. The matching should cover theentire...

CSerwangjun的博客 755

LeetCode10-Regular Expression Matching(动态规划、递归和Java库函数matches)

题目链接:https://leetcode.com/problems/regular-expression-matching/description/ 题意: 输入:待匹配的字符串S和正则表达式P,正则表达式P中的‘.’可以匹配任何字符,‘’可以匹配任何前面的字符n(n&amp;gt;=0)次。特别提醒:‘.’ 可以匹配n个‘.’并且这n个‘.’可以表示各自任何不同的字符(如:‘.*’可以和‘abc’...

Twilightuse93的专栏 768

DP动态规划专题十:LeetCode 10. Regular Expression Matching

LeetCode 10. Regular Expression Matching Given an input string (s) and a pattern §, implement regular expression matching with support for.and*..’ Matches any single character.*’ Matches ze...

katrina95的博客 225

LeetCode[动态规划] - #10 Regular Expression Matching

原题链接:#10 Regular Expression Matching   要求: 实现正则表达式匹配,支持'.'和'*'。   '.'匹配任意单字符。 '*'匹配任何0个或多个之前元素。   匹配应当覆盖整个输入字符串,而不仅仅是子串。   函数原型: boolean isMatch(String /* string to check */ s, String /* p...

Stay hungry, stay foolish. 242

老妈子级别大白话从零讲解LeetCode 10. Regular Expression Marching (HOT 100)

这两天翻了很多题解,思路讲解方面总是要么不够清楚要么有些许漏洞,不易于像我这样的新手理解;现在终于弄明白解题思路了,详细整理一下,希望能让更多的朋友少走弯路。 整理了递归和动态规划两种解法的思路,C++代码实现;动规运行时间4ms,84.63%,内存 6.2 MB,94.82%。

shuoO-24的空间站 302
上一篇: [LeetCode - 数学] 7. Reverse Integer
下一篇: [LeetCode - 双指针] 11. Container With Most Water
_tianyuxue
博客等级 码龄18年 11粉丝 81原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值