【问题描述】[困难]

请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。示例 1:输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母以及字符 . 和 *,无连续的 '*'。

【解答思路】

1. 动态规划




时间复杂度:O(N^2) 空间复杂度:O(1)

class Solution {public boolean isMatch(String A, String B) {int n = A.length();int m = B.length();boolean[][] f = new boolean[n + 1][m + 1];for (int i = 0; i <= n; i++) {for (int j = 0; j <= m; j++) {//分成空正则和非空正则两种if (j == 0) {f[i][j] = i == 0;} else {//非空正则分为两种情况 * 和 非*if (B.charAt(j - 1) != '*') {if (i > 0 && (A.charAt(i - 1) == B.charAt(j - 1) || B.charAt(j - 1) == '.')) {f[i][j] = f[i - 1][j - 1];}} else {//碰到 * 了,分为看和不看两种情况//不看if (j >= 2) {f[i][j] |= f[i][j - 2];}//看if (i >= 1 && j >= 2 && (A.charAt(i - 1) == B.charAt(j - 2) || B.charAt(j - 2) == '.')) {f[i][j] |= f[i - 1][j];}}}}}return f[n][m];}
}

思路二:

class Solution {public boolean isMatch(String s, String p) {int m = s.length();int n = p.length();boolean[][] f = new boolean[m + 1][n + 1];f[0][0] = true;for (int i = 0; i <= m; ++i) {for (int j = 1; j <= n; ++j) {if (p.charAt(j - 1) == '*') {f[i][j] = f[i][j - 2];if (matches(s, p, i, j - 1)) {f[i][j] = f[i][j] || f[i - 1][j];}}else {if (matches(s, p, i, j)) {f[i][j] = f[i - 1][j - 1];}}}}return f[m][n];}public boolean matches(String s, String p, int i, int j) {if (i == 0) {return false;}if (p.charAt(j - 1) == '.') {return true;}return s.charAt(i - 1) == p.charAt(j - 1);}
}
2. 递归

时间复杂度:O(N) 空间复杂度:O(1)

class Solution {public boolean isMatch(String A, String B) {// 如果字符串长度为0,需要检测下正则串if (A.length() == 0) {// 如果正则串长度为奇数,必定不匹配,比如 "."、"ab*",必须是 a*b*这种形式,*在奇数位上if (B.length() % 2 != 0) return false;int i = 1;while (i < B.length()) {if (B.charAt(i) != '*') return false;i += 2;}return true;}// 如果字符串长度不为0,但是正则串没了,return falseif (B.length() == 0) return false;// c1 和 c2 分别是两个串的当前位,c3是正则串当前位的后一位,如果存在的话,就更新一下char c1 = A.charAt(0), c2 = B.charAt(0), c3 = 'a';if (B.length() > 1) {c3 = B.charAt(1);}// 和dp一样,后一位分为是 '*' 和不是 '*' 两种情况if (c3 != '*') {// 如果该位字符一样,或是正则串该位是 '.',也就是能匹配任意字符,就可以往后走if (c1 == c2 || c2 == '.') {return isMatch(A.substring(1), B.substring(1));} else {// 否则不匹配return false;}} else {// 如果该位字符一样,或是正则串该位是 '.',和dp一样,有看和不看两种情况if (c1 == c2 || c2 == '.') {return isMatch(A.substring(1), B) || isMatch(A, B.substring(2));} else {// 不一样,那么正则串这两位就废了,直接往后走return isMatch(A, B.substring(2));}}}
}

【总结】

1.总想着正向解决问题,非但没有考虑清楚情况,而且不全面,没有发现子问题立即转化为递归或动态规划的思想
2.归纳整理总结 考虑清楚所有情况
3.动态规划流程

第 1 步:设计状态
第 2 步:状态转移方程
第 3 步:考虑初始化
第 4 步:考虑输出
第 5 步:考虑是否可以状态压缩

转载链接:https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/solution/zhu-xing-xiang-xi-jiang-jie-you-qian-ru-shen-by-je/

参考链接:https://leetcode-cn.com/problems/regular-expression-matching/solution/zheng-ze-biao-da-shi-pi-pei-by-leetcode-solution/

[Leedcode][第十题][剑指offer]面试题第[19]题[正则表达式][动态规划][递归][JAVA]相关推荐

  1. [剑指offer]面试题第[68-2]题[Leetcode][第236题][JAVA][二叉搜索树的最近公共祖先][递归]

    [问题描述][中等] 235/68-1 搜索二叉树 236/68-2 二叉树 [解答思路] 递归 时间复杂度:O(N) 空间复杂度:O(N) 情况 1. , 2. , 3. , 4. 的展开写法如下. ...

  2. [剑指offer]面试题第[57]题[Leetcode][第167题][JAVA][和为s的两个数字][两数之和][HashSet][二分][双指针]

    [剑指offer]面试题第[57]题[Leetcode][第167题][第1题] 有序无序之分 题目输出不同之分 以下解法按照[剑指offer]面试题第[57]题进行题解 [问题描述][简单] 输入一 ...

  3. [剑指offer]面试题第[59-2]题[JAVA][队列的最大值][暴力][双端队列]

    [问题描述][中等] [解答思路] 1. 暴力 复杂度分析 class MaxQueue {Queue<Integer> queue = new LinkedList();int maxV ...

  4. [剑指offer]面试题第[37]题[Leedcode][JAVA][第297题][二叉树列的序列化与反序列化][递归][BFS]

    [问题描述][中等] 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据.请设 ...

  5. [剑指offer]面试题第[68-1]题[Leedcode][JAVA][第235题][二叉搜索树的最近公共祖先][递归][BFS]

    [问题描述][第235题][二叉搜索树的最近公共祖先][简单] 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先.百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p. ...

  6. [剑指offer]面试题第[42]题[Leedcode][JAVA][第53题][最大子序和][动态规划][贪心][分治]

    [问题描述][第53题][最大子序和][中等] 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和.示例:输入: [-2,1,-3,4,-1,2,1, ...

  7. [剑指offer]面试题第[25]题[Leedcode][JAVA][第21题][合并两个有序链表]

    [问题描述][简单] 将两个升序链表合并为一个新的升序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例:输入:1->2->4, 1->3->4 输出:1-&g ...

  8. [剑指offer]面试题第[52]题[Leedcode][第160题][JAVA][相交链表][双指针]

    [问题描述][简单] [解答思路] 1. 双指针法 时间复杂度:O(N^2) 空间复杂度:O(1) public ListNode getIntersectionNode(ListNode headA ...

  9. [剑指offer]面试题第[28]题[Leedcode][JAVA][第101题][对称二叉树][队列][递归]

    [问题描述][简单] 给定一个二叉树,检查它是否是镜像对称的.例如,二叉树 [1,2,2,3,4,4,3] 是对称的.1/ \2 2/ \ / \ 3 4 4 3 [解答思路] 1. 递归 时间复杂度 ...

最新文章

  1. 永久设置SecureCRT的背景色和文字颜色方案
  2. android:layout_gravity=bottom不起作用问题
  3. Linux双机热备解决方案之Heartbeat
  4. iscroll.js 触屏手机web-kit浏览器滚动效果代码库
  5. 50条大牛C++编程开发学习建议
  6. Jmeter java协议配置文件导入
  7. java堆是gc管理_JVM内存管理及GC机制
  8. Kubernetes详解(八)——Kubernetes资源配置清单
  9. java tostring apache,Java如何使用Apache Commons Lang ToStringBuilder类?
  10. 信号完整性之传输线理论(三)
  11. Vue表格table样式
  12. arcos的matlab定义,想用matlab解一个带arccos的方程。可是结果好像没有解析解。求帮助解数值解...
  13. CDR2021安装教程 CorelDRAW 2021完整版下载
  14. (附源码)ssm通用数据展示系统 毕业设计200934
  15. Aborted (core dumped)
  16. 64位 window 在notepad++中添加HexEditor工具
  17. 04-2. 打印九九口诀表(15)
  18. 解决Jenkins中Maven本地仓库更新不及时的问题
  19. 利用python批量合并excel和word内的表格
  20. Windows Terminal+zsh

热门文章

  1. js获取checkbox值的方法
  2. geoserver native JAI error 问题解决方法
  3. web控件开发系列(四) 自定义控件属性(下)
  4. [MOSS开发]:如何使用用户控件
  5. java8 stream to map_Java 8 Stream Api 中的 map和 flatMap 操作
  6. Spring Boot 2.1 版本变化[翻译]
  7. 认识 react 的钩子函数
  8. 大厂Java岗面试心得记录
  9. SpringBoot如何切换Redis默认库
  10. iview tag 标签点击事件