leetcode-10. Regular Expression Matching

Posted perfy576

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-10. Regular Expression Matching相关的知识,希望对你有一定的参考价值。

1 题目

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

实现(implemement)正则表达式,支持.和*

‘.‘ 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

 

1 分析

难点在于*的处理

*可能做0,1,n来处理

 

使用s1,s2表示两个字符串的开始位置。

当s2+1 位置是0,并且s1,s2位置的字符相等的时候。

那么就分别处理*是0,1,n的情况

 

bool solve(string str1, int s1, string p, int s2)
{
    if (str1.size() == s1 && p.size() == s2)
    {
        return true;
    }

    if (str1.size() < s1 && p.size() == s2)
    {
        return false;
    }

    // 当下个字符是 * 的时候,那么会存在,* 当 0 ,1,n处理
    if (p[s2 + 1] == ‘*‘)
    {
        if (str1[s1] == p[s2] || (p[s2] == ‘.‘ && str1.size() != s1))
        {
            // solve(str1, s1 + 1, p, s2 + 2)  是 * 当 1 处理
            // solve(str1, s1, p, s2 + 2) 是* 当0处理
            //  solve(str1, s1 + 1, p, s2) 是 * 当 n 处理,所以str1 动,但是p不懂
            return solve(str1, s1 + 1, p, s2 + 2) 
                    || solve(str1, s1, p, s2 + 2) || solve(str1, s1 + 1, p, s2);
        }
        else
        {
            // 如果  str1[s1] == p[s2] 那么 * 一定当0 处理
            return solve(str1, s1, p, s2 + 2);
        }
    }
    else
    {
        // 不相等的情况下都移动
        if (p[s2] == str1[s1] || (p[s2] == ‘.‘ && s1 < str1.size()))
        {
            return solve(str1, s1 + 1, p, s2 + 1);
        }
    }
}

 

 

 

但是上面的方法会超时,应该是处理了大量的子问题?

 

动态规划的方法:

思想是,使用dp数组,记录str长为i,p长为j时的匹配状况。

因此,当p[j]时*的时候,要分别记录,*按照0,1,n取的情况。

当*按照n取的时候,是要等于dp[i-1][j]的

class Solution
{
  public:
    bool isMatch(string s, string p)
    {
        int m = s.size(), n = p.size();
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
        dp[0][0] = true;
        for (int i = 0; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (p[j - 1] == ‘*‘)
                {
                    // =dp[i][j - 2]  表示 * 按照 0处理,也就是p中没有 *前面的字符
                    // i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == ‘.‘  表示 * 当1处理
                    // 并且 * 当 1 处理的前提是,dp[i - 1][j] 也就是说,
                    // p中前一个已经匹配了 * 前面的字符
                    dp[i][j] = dp[i][j - 2] || (i > 0 && 
                            (s[i - 1] == p[j - 2] || p[j - 2] == ‘.‘) && dp[i - 1][j]);
                }
                else
                {
                    // 当不是*的时候,就需要 p中字符匹配s中字符或是 p 中字符是 .

                    dp[i][j] = i > 0 && dp[i - 1][j - 1] 
                            && (s[i - 1] == p[j - 1] || p[j - 1] == ‘.‘);
                }
        return dp[m][n];
    }
};

 

以上是关于leetcode-10. Regular Expression Matching的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 10. Regular Expression Matching

leetcode 10. Regular Expression Matching

Leetcode 10: Regular Expression Matching

[LeetCode #10] Regular Expression Matching

[LeetCode] 10. Regular Expression Matching ☆☆☆☆☆

leetcode-10. Regular Expression Matching