【重点 递归 动态规划 正则表达式】LeetCode 10. Regular Expression Matching

LeetCode 10. Regular Expression Matching

本博客参考:http://www.cnblogs.com/grandyang/p/4461713.html
详细解析见另一题:【重点】剑指offer——面试题53:正则表达式匹配里面的代码风格是C的,现在把它改成C++风格的代码。在剑指offer53题的代码中,由于代码风格的原因,未考虑p.size() == 1的情况,这里也做了适当修改
Solution1:递归
代码中的注释写的不是太清楚,加一点:
一、当模式中的第二个字符不是“*”时:
1、如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
2、如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。
二、当模式中的第二个字符是“*”时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式:
1、x*匹配0个字符。模式后移2字符,相当于x*被忽略;(一开始忘了即使当前字符匹配,也存在忽略掉的情况!!!)
2、x*匹配1个字符。字符串后移1字符,模式后移2字符;
3、x*匹配多于1个字符。字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;
注意:情况2可以被情况1和情况3包含。执行一次情况3,再执行一次情况1,就相当于情况2。

class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.empty()) return s.empty();
        if (p.size() == 1) {
            return (s.size() == 1 && (s[0] == p[0] || p[0] == '.'));
        }
        //if the next character in pattern is not '*'
        if (p[1] != '*') {
            if (s[0] == p[0] || (!s.empty() && p[0] == '.'))
                return isMatch(s.substr(1), p.substr(1));
            else
                return false;
        }
        //if the next character is '*'
        else {
            if (s[0] == p[0] || (!s.empty() && p[0] == '.'))
                return isMatch(s, p.substr(2)) || isMatch(s.substr(1), p);
                //刚开始一直不懂为何要返回match(str, pattern+2)的值,原因在于'*'可以匹配0个字符
                //即使是当前字符匹配,也存在匹配0个字符的情况
            else
                return isMatch(s, p.substr(2));
        }
    }
};

Solution2:动态规划
我们也可以用DP来解,定义一个二维的DP数组,其中dp[i][j]表示s[0,i)和p[0,j)是否match,然后有下面三种情况(下面部分摘自这个帖子):
1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != ‘*’ && (s[i - 1] == p[j - 1] || p[j - 1] == ‘.’);
2. P[i][j] = P[i][j - 2], if p[j - 1] == ‘*’ and the pattern repeats for 0 times;
3. P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == ‘.’), if p[j - 1] == ‘*’ and the pattern repeats for at least 1 times.

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 (j > 1 && p[j - 1] == '*') {
                    dp[i][j] = dp[i][j - 2] 
                    || (i > 0 && (s[i - 1] == p[j - 2] 
                    || p[j - 2] == '.') && dp[i - 1][j]);
                } else {
                    dp[i][j] = i > 0 && dp[i - 1][j - 1] 
                    && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
                }
            }
        }
        return dp[m][n];
    }
};

猜你喜欢

转载自blog.csdn.net/Allenlzcoder/article/details/80667874
今日推荐