题目描述
请实现一个函数用来匹配包含$’. ‘$和$’‘$的正则表达式。模式中的字符$’.’$表示任意一个字符,而$’‘$表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串$”aaa”$与模式$”a.a”$和$”abaca”$匹配,但与$”aa.a”$和$”ab*a”$均不匹配。
示例 1:
1 | 输入: |
示例 2:
1 | 输入: |
示例 3:
1 | 输入: |
示例 4:
1 | 输入: |
示例 5:
1 | 输入: |
- $s$ 可能为空,且只包含从 $a-z$ 的小写字母。
- $p$ 可能为空,且只包含从 $a-z$ 的小写字母以及字符 $.$ 和 $$,无连续的 $’‘$。
注意:本题与主站 10 题相同:https://leetcode-cn.com/problems/regular-expression-matching/
算法
(动态规划) $O(n^2)$
状态表示:$s$ 的前 $i$ 个字母 s[1~i]
和 $p$ 的前 $j$ 个字母是否匹配(下标从 $1$ 开始比较方便 )
状态计算:根据 p[j + 1]
是否为 *
分情况讨论,因为如果 p[j +1] = *
时那么 p[j-j+1]
是一个整体。($*$ 表示前面的一个字符可以出现任意多次)
特判:如果 $p[j + 1]$ 是 $*$ 的话那么不处理当前字符 $p[j]$,continue
,将它们作为一个整体处理,
- 如果当前字符 $p[j]$ 不是
*
,则f[i][j] = true
当且仅当s[1~i-1]
和p[1~j-1]
匹配且 s[i] 和 p[j] 匹配(或者p[j] == '.'
也是匹配的)f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');
- 如果当前字符 $p[j]$ 是
*
,则遍历 $*$ 号前面的字符出现从 $0$ 次到任意多次与 $s[i]$ 进行匹配。f[i][j] = f[i][j - 2] || (i && f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.'));
,这里经过了状态转移优化,这个优化类似于完全背包优化,都是用f[i - 1][j]
替换了除出现 $0$ 次以外的循环遍历。
时间复杂度
$O(n^2)$
空间复杂度
$O(n^2)$
C++ 代码
1 | class Solution { |