leetcode difficulty - regular expression matching (super detailed ideas, recursion or dp)

Title:
Given you a string s and a character pattern p, please implement a regular expression matching that supports '.' and ' '.
'.' Match any single character
'
' Match zero or more of the previous element The
so-called match is to cover the entire string s, not part of the string.

answer

① Recursion:
It is to consider each situation
(each situation is written in the comment)

class Solution {
public:
    string sss, ppp;
    bool solve(int a, int b) {
    	// 避免最后 a 匹配完,b 还剩下 "a*b*c*",这种也算完全匹配
        if(a == sss.size()) {
            while(b < ppp.size() - 1) {
                if(ppp[b + 1] == '*') {
                    b = b + 2;
                }
                else {
                    break;
                }
            }
        }
        // 递归终止条件,如果都到了字符串末尾,则完全匹配
        if(a == sss.size() && b == ppp.size()) {
            return true;
        }
        // 递归终止条件,如果其中一个到了字符串末尾,另一个没到末尾,则不是完全匹配
        if((a == sss.size() || b == ppp.size()) && (a + b != sss.size() + ppp.size())) {
            return false;
        }
        // 如果该字符后面有 '*'
        if(b < ppp.size() - 1 && ppp[b + 1] == '*') {
        	// 如果有重复的 "a*a*a*",只用看作一个 'a*',特别的如果存在 '*',例 "a*.*",可以看成 ".*"
            if(b < ppp.size() - 3 && ppp[b + 3] == '*') {
                if(ppp[b + 2] == '.' || ppp[b + 2] == ppp[b]) {
                    return solve(a, b + 2);
                }
            }
            // 如果字符相同,则可以选择不匹配,或者匹配
            if(sss[a] == ppp[b] || ppp[b] == '.') {
                return solve(a + 1, b) || solve(a, b + 2);
            }
            // 如果字符不相同,则只能跳过,并且得跳过两个 '*' 也要被跳过
            else {
                return solve(a, b + 2);
            }
        }
        // 如果该字符后面没有 '*'
        else {
         	// 如果相同则匹配
            if(sss[a] == ppp[b] || ppp[b] == '.') {
                return solve(a + 1, b + 1);
            }
            // 如果不相同则不匹配
            else {
                return false;
            }
        }
    }
    bool isMatch(string s, string p) {
        sss = s;
        ppp = p;
        // 从两个字符串的开头开始进行匹配
        return solve(0, 0);
    }
};

② dp
defines an array dp[i][j], which represents whether the first i strings of p match the first j strings of s. First,
dp[0][0] must match, especially, similar to "a a " It also matches "", so we need to consider when preprocessing
Next is similar to recursion, considering each case

class Solution {
public:
    bool dp[35][35];
    bool isMatch(string s, string p) {
        dp[0][0] = true;
        int f = 2;
        while(f <= p.size()) {
            if(p[f - 1] == '*') {
                dp[f][0] = true;
            }
            else {
                break;
            }
            f = f + 2;
        }
        for(int i = 1; i <= p.size(); i++) {
            for(int j = 1; j <= s.size(); j++) {
                if(p[i - 1] == '*') {
                    dp[i][j] = dp[i - 1][j];
                }
                else if(i < p.size() && p[i] == '*') {
                    if(p[i - 1] == s[j - 1] || p[i - 1] == '.') {
                        dp[i][j] = (dp[i - 1][j - 1] || dp[i - 1][j] || dp[i][j - 1]);
                    }
                    else {
                        dp[i][j] = dp[i-1][j];
                    }
                }
                else if(p[i - 1] == s[j - 1] || p[i - 1] == '.') {
                    dp[i][j] = dp[i - 1][j - 1];
                }
                else {
                    dp[i][j] = false;
                }
            }
        }
        return dp[p.size()][s.size()];
    }
};

Guess you like

Origin blog.csdn.net/m0_52212261/article/details/128891928