剑指 Offer 19. 正则表达式匹配
字符串处理,动态规划
题目链接-来源:力扣(LeetCode)
请实现一个函数用来匹配包含’. ‘和’*‘的正则表达式。模式中的字符’.’表示任意一个字符,而’*‘表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但与”aa.a”和”ab*a”均不匹配。
示例 1:
输入:
s = “aa”
p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。
思路:
本题是一道动态规划处理字符串的的经典题目。
对于’.’,一个简化的考虑就是,我们设计一个方法 match(char a, char b),当且仅当 a = b 或者 a、b之中任意一个为’.’时返回 true 。
我们用 f(i, j)表示 s截至第i - 1个字符s[i - 1]的子串,与 p截至第j - 1个字符p[j - 1]的子串 是匹配的。那么我们要考虑的问题就是,f(i + 1, j)是否成立,f(i, j + 1)是否成立。
注意,f(0, n) 和 f(m, 0) 分别对应「s为空串」以及「p为空串」的情况,因此除了 f(0, 0) = true,其他的 0 行 0 列我们都要初始化为 false。
首先,对于p[j - 1] != ‘*‘的情况,我们有 f(i, j) = f(i - 1, j - 1) && match(s[i - 1], p[j - 1])
下面考虑p[j - 1] == ‘*‘ 的复杂情况。记住,我们考虑状态转移时保持 s 的指针[i - 1]不动,也就是说,我们先比较了f(i, j -2), f(i, j - 1), 之后才来到了 f(i, j)。
- 此时,若p[j - 2] + ‘*‘视为无效串(即 p[j - 2]出现了0次),则 f(i, j) 回退到 f(i, j - 2) 的状态。
- p[j - 2]已经出现过了,我们再让其多出现一次,看能否匹配,也就是我们要比较 mtach(s[i - 1], p[j - 2]),若成功,则 f(i, j) 的状态可以回退到 f(i - 1, j)。
以上两种情况取并运算 ‘||’,即完成状态的转移。
时间复杂度:O(mn) n为 s 长度,m为 p 长度
空间复杂度:O(mn)
实现:
1 | class Solution { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.