题目描述
请实现一个函数用来匹配包含.和*的正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任意次(含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的索引和字符串索引所代表的字符位置。