目录
题目:
给你一个字符串
s
和一个字符规律p
,请你来实现一个支持'.'
和'*'
的正则表达式匹配。
'.'
匹配任意单个字符'*'
匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个字符串
s
的,而不是部分字符串。示例 1:
**输入:**s = "aa", p = "a" **输出:**false **解释:**"a" 无法匹配 "aa" 整个字符串。
示例 2:
**输入:**s = "aa", p = "a*" **输出:**true **解释:**因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
**输入:**s = "ab", p = ".*" **输出:**true **解释:**".*" 表示可匹配零个或多个('*')任意字符('.')。
提示:
1 <= s.length <= 20
1 <= p.length <= 20
s
只包含从a-z
的小写字母。p
只包含从a-z
的小写字母,以及字符.
和*
。- 保证每次出现字符
*
时,前面都匹配到有效的字符
1. 思路
这是一个经典的动态规划问题。我们可以使用动态规划来解决这个问题,定义状态 dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。然后,我们根据模式 p 的第 j 个字符的不同情况进行讨论。
2. 解题方法
- 定义一个二维数组 dp,其中 dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。
- 初始化 dp[0][0] 为 true,表示空字符串与空模式匹配。
- 初始化第一行,即 dp[0][j],根据模式 p 的特性进行初始化,如果模式 p 的第 j 个字符为 ‘',则 dp[0][j] = dp[0][j-2],因为 '’ 可以匹配零个前面的元素。
- 对于状态转移方程,当 s[i-1] 与 p[j-1] 匹配时,即 s 的第 i 个字符与 p 的第 j 个字符相等或者 p 的第 j 个字符为 ‘.’,则有两种情况:
- 当 p[j-1] 不为 ‘*’ 时,即 p 的第 j 个字符为普通字符,那么 dp[i][j] = dp[i-1][j-1]。
- 当 p[j-1] 为 ‘’ 时,即 p 的第 j 个字符为 '’,有两种情况:
- ‘’ 匹配零个前面的元素,即忽略 '’ 及其前面的那个字符,那么 dp[i][j] = dp[i][j-2]。
- ‘*’ 匹配一个或多个前面的元素,即将 s 的第 i 个字符与 p 的前 j-1 个字符进行匹配,那么 dp[i][j] = dp[i-1][j]。
- 最后返回 dp[s.length()][p.length()]。
3. 复杂度
- 时间复杂度:O(mn),其中 m 和 n 分别是字符串 s 和模式 p 的长度。
- 空间复杂度:O(mn),需要一个二维数组来存储状态。
4. Code