LeetCode之正则表达式匹配(Top 100)

开发 前端
已知一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。

[[438356]]

前言

本题为 LeetCode 前 100 高频题

我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。微博:@故胤道长[1])的 Swift 算法题题解整理为文字版以方便大家学习与阅读。

LeetCode 算法到目前我们已经更新了 9 期,我们会保持更新时间和进度(周一、周三、周五早上 9:00 发布),每期的内容不多,我们希望大家可以在上班路上阅读,长久积累会有很大提升。

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。

难度水平:困难

1. 描述

已知一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

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

所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。

2. 示例

示例 1

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

示例 2

  1. 输入:s = "aa" p = "a*" 
  2. 输出:true 
  3. 解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。 

示例 3

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

示例 4

  1. 输入:s = "aab" p = "c*a*b" 
  2. 输出:true 
  3. 解释:因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。 

示例 5

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

约束条件:

  • 1 <= s.length <= 20
  • 1 <= p.length <= 30
  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
  • 保证每次出现字符 * 时,前面都匹配到有效的字符

3. 答案

  1. class RegularExpressionMatching { 
  2.     func isMatch(_ s: String, _ p: String) -> Bool { 
  3.         let sChars = Array(s), pChars = Array(p) 
  4.         var dp = Array(repeating: Array(repeating: falsecount: pChars.count + 1), count: sChars.count + 1) 
  5.         dp[0][0] = true 
  6.          
  7.         for i in 0...pChars.count { 
  8.          // jump over "" vs. "x*" case 
  9.             dp[0][i] = i == 0 || i > 1 && dp[0][i - 2] && pChars[i - 1] == "*" 
  10.         } 
  11.          
  12.         for i in 0...sChars.count { 
  13.             for j in 0...pChars.count { 
  14.                 guard j > 0 else { 
  15.                     continue 
  16.                 } 
  17.                  
  18.                 let pCurrent = pChars[j - 1] 
  19.                  
  20.                 if pCurrent != "*" { 
  21.                     dp[i][j] = i > 0 && dp[i - 1][j - 1] && (pCurrent == "." || pCurrent == sChars[i - 1]) 
  22.                 } else { 
  23.                     dp[i][j] = dp[i][j - 2] || i > 0 && j > 1 && (sChars[i - 1] == pChars[j - 2] || pChars[j - 2] == ".") && dp[i - 1][j] 
  24.                 } 
  25.             } 
  26.         } 
  27.          
  28.         return dp[sChars.count][pChars.count
  29.     } 
  • 主要思想:经典二维动态规划
  • 时间复杂度: O(mn)
  • 空间复杂度: O(mn)

该算法题解的仓库:LeetCode-Swift[2]

前往 LeetCode[3] 练习

参考资料

[1]@故胤道长: https://m.weibo.cn/u/1827884772

[2]LeetCode-Swift: https://github.com/soapyigu/LeetCode-Swift

[3]LeetCode: https://leetcode.com/problems/regular-expression-matching

 

责任编辑:姜华 来源: Swift社区
相关推荐

2009-08-20 14:26:51

C#正则表达式

2009-09-16 16:22:04

正则表达式匹配

2017-05-12 10:47:45

Linux正则表达式程序基础

2009-09-16 18:08:14

正则表达式匹配单词

2012-04-28 15:22:46

PHP

2009-06-08 16:49:05

Java正则表达式group

2010-03-04 15:20:20

Ubuntu Patt

2010-03-15 16:21:28

Python正则表达式

2009-08-20 13:38:58

C#正则表达式

2009-09-16 13:24:30

PHP正则表达式匹配

2009-09-16 16:48:03

正则表达式匹配数字

2018-09-27 15:25:08

正则表达式前端

2020-09-04 09:16:04

Python正则表达式虚拟机

2009-09-16 13:53:17

PHP正则表达式匹配

2009-06-10 13:51:25

Java正则表达式匹配替换

2010-07-21 10:43:25

Perl正则表达式匹配

2009-09-16 17:02:15

正则表达式匹配字符串

2009-09-16 17:38:49

正则表达式匹配任意字符

2010-03-10 18:57:53

Python正则表达式

2009-09-16 17:15:57

正则表达式引擎
点赞
收藏

51CTO技术栈公众号