题目描述
请实现一个函数用来匹配包含.
和*
的正则表达式。模式中的字符.
表示任意一个字符,而*
表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”abaca”匹配,但与”aa.a”和”ab*a”均不匹配。
示例 1:
输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 2:
输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母以及字符.
和*
,无连续的'*'
。
解题思路
方法:普通分析
时间复杂度:$O(N^2)$
空间复杂度:$O(N^2)$
代码如下
class Solution {
public:
bool isMatch(string s, string p) {
vector<vector<int> > matrix(p.size()+1,vector<int>(s.size()+1,0));
matrix[0][0] = 1;
for(int i=0; i<p.size(); i++){
if(i>=1 && p[i]=='*' && matrix[i-1][0]==true){
matrix[i+1][0] = true;
}
}
for(int i=0; i<p.size(); i++){//正则串
for(int j=0; j<s.size(); j++){//字符串
if(p[i]=='.' || p[i]>='a'&&p[i]<='z'){
if(p[i]=='.'){
matrix[i+1][j+1] = matrix[i][j];
}
else
{
if(p[i]==s[j])
matrix[i+1][j+1] = matrix[i][j];
}
}
if(p[i]=='*'){
//不看
if(i>=1){
matrix[i+1][j+1] |= matrix[i-1][j+1];
}
//看
if(i>=1 && (p[i-1]==s[j] || p[i-1]=='.')){
matrix[i+1][j+1] |= matrix[i+1][j];
}
}
}
}
return matrix[p.size()][s.size()];
}
};
解法分析
假设主串为 $A$,模式串为 $B$ 从最后一步出发,需要关注最后进来的字符。假设 $A$ 的长度为 $n$,$B$ 的长度为 $m$ ,关注正则表达式 $B$ 的最后一个字符是谁,它有三种可能,正常字符、$*$ 和 $.$(点),那针对这三种情况讨论即可,如下:
解法注意点
- 需要对空字符串或者空匹配串进行单独判断。
- 不能弄混matrix的索引和字符串索引所代表的字符位置。