10. 正则表达式匹配
题目解析:
给你一个字符串 s
和一个字符规律 p
,请你来实现一个支持 '.'
和 '*'
的正则表达式匹配。
'.'
匹配任意单个字符'*'
匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s
的,而不是部分字符串。
解题思路:
算法思路:
1.
状态表⽰:
对于两个字符串之间的
dp
问题,我们⼀般的思考⽅式如下:
i.
选取第⼀个字符串的
[0, i]
区间以及第⼆个字符串的
[0, j]
区间当成研究对象,结
合题⽬的要求来定义「状态表⽰」;
ii.
然后根据两个区间上「最后⼀个位置的字符」,来进⾏「分类讨论」,从⽽确定「状态转移
⽅程」。
我们可以根据上⾯的策略,解决⼤部分关于两个字符串之间的
dp
问题。
因此我们定义状态表⽰:
dp[i][j]
表⽰:字符串
p
的
[0, j]
区间和字符串
s
的
[0, i]
区间是否可以匹配。
2.
状态转移⽅程:
⽼规矩,根据最后⼀个位置的元素,结合题⽬要求,分情况讨论:
a.
当
s[i] == p[j]
或
p[j] == '.'
的时候,此时两个字符串匹配上了当前的⼀个字符,
只能从
dp[i - 1][j - 1]
中看当前字符前⾯的两个⼦串是否匹配。只能继承上个状态中
的匹配结果,
dp[i][j] = dp[i - 1][j - 1]
;
b.
当
p[j] == '*'
的时候,和上道题稍有不同的是,上道题
"*"
本⾝便可匹配
0 ~ n
个
字符,但此题是要带着
p[j - 1]
的字符⼀起,匹配
0 ~ n
个和
p[j - 1]
相同的字
符。此时,匹配策略有两种选择:
▪
⼀种选择是:
p[j - 1]*
匹配空字符串,此时相当于这两个字符都匹配了⼀个寂寞,直
接继承状态
dp[i][j - 2]
,此时
dp[i][j] = dp[i][j - 2]
;
▪
另⼀种选择是:
p[j - 1]*
向前匹配
1 ~ n