给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符。
'*' 匹配零个或多个前面的元素。

匹配应该覆盖整个字符串 (s) ,而不是部分字符串。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *

示例 1:

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

示例 2:

输入:
s = "aa"
p = "a*"
输出: true
解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。

示例 3:

输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。

示例 4:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。

示例 5:

输入:
s = "mississippi"
p = "mis*is*p*."
输出: false

思路:如果不用递归的方法,一点一点的判断,比如如果当前的p[j]为*,那么如果s的当前值与p[j-1]相等,就i++。这样存在的问题是,不能判断出*到底代替几个p[j-1],所以我们还是用递归的方法。

 bool isMatch(string s, string p) {  

        int pLen=p.length();
int sLen=s.length(); if(pLen==0)
return sLen==0; if(pLen==1)
if( (s[0]==p[0] || p[0]=='.') && sLen==1)
return true;
else
return false; if(p[1]!='*')
{
if(s.length()>0 && (s[0]==p[0] || p[0]=='.'))
return isMatch(s.substr(1),p.substr(1));
else
return false;
}
else
{
while(s.length()>0 && (p[0]==s[0] || p[0]=='.'))
{
if(isMatch(s,p.substr(2)))//*表示0个字符
return true;
s=s.substr(1);
}
return isMatch(s,p.substr(2));
}
}
上述程序就将*分成了两种情况,一种是*代表0个字符,一种是*代表1个或多个字符。首先每次判断代表0个字符是否符合,如果不符合,那么就先代表一个,将s的首字符去掉,接着判断,这样*就代表了一个或多个。
还有一种DP的思路,是用空间换时间。额外申请一个数组作为辅助,记录前面的结果。dp[i][j]代表s[0..i-1]和p[0...j-1]的匹配,0代表匹配失败,1代表匹配成功。那么可以得到,dp[0][0]=1表示空串与空串是匹配的,dp[i][0]=0,表示如果p是空串,那么一定不匹配。dp[0][j]表示s是空串,这种情况如果p是x*的组合,是可以匹配的,否则匹配失败。而且dp[0][1]=0表示如果s为空串,p只有一个字符时,肯定匹配失败。dp[i][j]我们可以分为p[j-1]为*和不为*的情况,(1)如果p[j-1]也就是p的最后一个元素为*,那么还可以分为它代表0个前面的元素,也就是说s[0..i-1]与p[0..j-3]是要匹配的,即dp[i][j-2]=1。或者它代表一个或多个前面的元素,那么s[0..i-2]与p[0..j-1]是匹配的,并且s的最后一个元素s[i-1]还要与p的倒数第二个相等,即s[i-1]==p[i-2].
  bool isMatch(string s, string p)
{
int m=s.size()+1,n=p.size()+1;
vector<vector<bool> > dp(m,vector<bool>(n));
dp[0][0] = true;//s无字符,p无字符
dp[0][1] = false;//s无字符,p有一个字符(且不能省略)
for (int i = 1; i <= s.size(); ++i)
dp[i][0] = false;//s有字符,p无字符
for (int j = 2; j <= p.size(); ++j)//Ax*只有A与空串匹配,且后两个字符是x*的形式才匹配
dp[0][j] = (p[j - 1] == '*') && dp[0][j - 2];
for (int j = 1; j <= p.size(); ++j)
for (int i = 1; i <= s.size(); ++i) {
if (p[j - 1] != '*') //如果不是*,只有p遍历到.或者p[j-1]和s[i-1]相等的时候匹配
dp[i][j] = dp[i - 1][j - 1] && (p[j - 1] == '.' || s[i - 1] == p[j - 1]);
else dp[i][j] = dp[i][j - 2] ||//x*表示0个x的情况
(dp[i - 1][j - 2] && (p[j - 2] == '.' || p[j - 2] == s[i - 1])) ||//x*表示1个x的情况
//x*表示多个x的时候表示,此时必须s[0~i-2]与p[0~j-1]匹配且……
(dp[i - 1][j] && (p[j - 2] == '.' || p[j - 2] == s[i - 1]));
}
return dp[s.size()][p.size()];
}

Leetcode(10)-正则表达式匹配的更多相关文章

  1. Leetcode 10. 正则表达式匹配 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  2. Java实现 LeetCode 10 正则表达式匹配

    10. 正则表达式匹配 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配, ...

  3. [LeetCode] 10. 正则表达式匹配

    题目链接:https://leetcode-cn.com/problems/regular-expression-matching/ 题目描述: 给定一个字符串 (s) 和一个字符模式 (p).实现支 ...

  4. LeetCode 10. 正则表达式匹配(Regular Expression Matching)

    题目描述 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或多个前面的元素. 匹配应该覆盖整个字符串 (s ...

  5. LeetCode 10——正则表达式匹配

    1. 题目 2. 解答 在 回溯算法 中我们介绍了一种递归的思路来求解这个问题. 此外,这个问题也可以用动态规划的思路来解决.我们定义状态 \(P[i][j]\) 为子串 \(s[0, i)\) 和 ...

  6. leetcode题目10.正则表达式匹配(困难)

    题目描述: 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符'*' 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个  ...

  7. 【LeetCode】正则表达式匹配(动态规划)

    题目描述 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或多个前面的元素. 匹配应该覆盖整个字符串 (s ...

  8. LeetCode10. 正则表达式匹配

    10. 正则表达式匹配 描述 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或多个前面的元素. 匹配应该 ...

  9. leetcode 10 Regular Expression Matching(简单正则表达式匹配)

    最近代码写的少了,而leetcode一直想做一个python,c/c++解题报告的专题,c/c++一直是我非常喜欢的,c语言编程练习的重要性体现在linux内核编程以及一些大公司算法上机的要求,pyt ...

  10. Leetcode(10)正则表达式匹配

    Leetcode(10)正则表达式匹配 [题目表述]: 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或 ...

随机推荐

  1. sap的内核升级,修补了源代码保护的方式

    众所周知,在SAP的内核位701或者之前的版本中,我们可以通过向源代码的中加入"*@#@@[SAP]"这样的代码,来实现对源代码的保护.但是在内核升级到721和以后的版本中,你会发 ...

  2. Pytorch入门——手把手教你MNIST手写数字识别

    MNIST手写数字识别教程 要开始带组内的小朋友了,特意出一个Pytorch教程来指导一下 [!] 这里是实战教程,默认读者已经学会了部分深度学习原理,若有不懂的地方可以先停下来查查资料 目录 MNI ...

  3. centos7搭建dolphinscheduler集群

    一.简述 Apache DolphinScheduler是一个分布式去中心化,易扩展的可视化DAG工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用.有 ...

  4. linux中的虚拟环境工具

    1.虚拟环境工具的学习 python的虚拟环境,其实就是在机器上,方便的创建出多个解释器,每个解释器运行一个项目,互相之间不受影响 2.virtualenv工具,可以方便的创建,使用,删除也很方便 3 ...

  5. IDE 阅读代码时候如何防止误触

    在 JetBrains 系列的编辑器中,点击右下角小锁图标,就可以只读防止误修改. Visual Studio 下安装 CodeMaid 插件 http://www.codemaid.net/ htt ...

  6. 简单makefile

    https://www.cnblogs.com/prettyshuang/p/5552328.html#_label0

  7. Python学习【第6篇】:集合的定义和基本方法

    1.概念 (1)不同元素组成 例: s = {1,2,3,4,4,4,4,4,4}print(s)运行结果:{1, 2, 3, 4}因为是不同元素组成,因此去重了 (2)无序 例: s = {&quo ...

  8. java实现注销登录

    servlet HttpServletRequest request HttpSession session=request.getSession(); session.removeAttribute ...

  9. (二)基于shard-jdbc中间件,实现数据分库分表

    基于shard-jdbc中间件,实现数据分库分表 Sharding-JDBC简介 Sharding配置示意图 1.水平分割 1.1 水平分库 1.2 水平分表 2.Shard-jdbc中间件 2.1 ...

  10. spring MVC 3.2中@ResponseBody(Post接口)返回乱码的完美解决方案

    本来因为ajax跨域http远程调用时有问题,在服务端响应时用以下方式解决了,但IE8及下有问题. response.addHeader("Access-Control-Allow-Orig ...