leetcode题解c++ | 10. Regular Expression Matching

题目:https://leetcode.com/problems/regular-expression-matching/#/description

Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
分析

刚开始想直接匹配,但对于带*的,就很难做判断。想了很久才想通dp来做比较简单

f[i][j]: s[0..i-1] 是否匹配p[0..j-1]

if p[j - 1] != '*'

     f[i][j] = f[i-1][j-1]&& (p[j-1]=='.'||s[i-1]==p[j-1])

if p[j - 1] == '*', 设 p[j - 2] 为 x

      1) "x*" 重复0次:f[i][j] = f[i][j - 2]

      2)"x*" 重复1次以上:f[i][j] = f[i-1][j] && (p[j-2]=='.'||s[i-1]==p[j-2])

注意这里只需要转移重复一次的情况,而不需要枚举重复的次数。还有初始化需要分类,这个想一下也很容易想通。

c++实现:

bool isMatch(string s, string p)
{
    int m=s.length(), n=p.length();
    bool f[m+1][n+1];
    f[0][0] = 1;
    for(int i=1; i<=m; ++i)
        f[i][0] = 0;
    for(int i=1; i<=n; ++i)
        if(p[i-1]!='*')
            f[0][i] = 0;
        else
            f[0][i] = f[0][i-2];
    for(int i=1; i<=m; ++i)
        for(int j=1; j<=n; ++j)
        {
            if(p[j-1]!='*')
                f[i][j] = f[i-1][j-1]&& (p[j-1]=='.'||s[i-1]==p[j-1]);
            else
                f[i][j] = f[i][j-2] || (f[i-1][j]&& (p[j-2]=='.'||s[i-1]==p[j-2]));
        }
    return f[m][n];
}





你可能感兴趣的:(leetcode)