[leetcode -- backtracking] 10. Regular Expression Matching

题目: 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

Regular Expression Matching

分析: 这是一道比较难的题目. 解决思路是先看字符串spij开始的子串是否匹配, 用递归的方法直到串的最后, 最后回溯得到结果. 假设现在走到si位置, pj位置, 分以下两种情况讨论:

  1. p[j+1] != '*': 这种情况比较直观, 直接判断si位置和'p'的'j'位置上的字符是否相同即可(如果p[j] == '.'则认为相同). 如果不相同则返回false, 否则递归下一层i+1, j+1.
  2. p[j+1] == '*': 那么此时要看从s[i]开始的子串, 假设s[i], s[i+1]...s[i+k]都等于p[j]那么意味着这些都有可能是合适的匹配, 那么递归对于剩下的(i, j+2), (i+1, j+2)...(i+k, j+2)位置进行尝试(j+2是因为要跳过当前字符和下一个*).

code:

class Solution {
public:
    bool isMatch(string s, string p) {
        return helper(s, 0, p, 0);
    }
    
    bool helper(string& s, int i, string& p, int j) {
        // 看s和p从i和j开始的子串是否匹配
        if(j == p.length())
            return i == s.length();
        // p[j+1] != '*'
        if(j == p.length() - 1 || p[j+1] != '*') {
            if(i == s.length() || s[i] != p[j] && p[j] != '.')
                return false;
            else
                return helper(s, i+1, p, j+1);
        }
        // p[j+1] == '*'
        while(i < s.length() && (s[i] == p[j] || p[j] == '.')) {
            if(helper(s, i, p, j+2))
                return true;
            ++i;
        }
        return helper(s, i, p, j+2);
    }
};

你可能感兴趣的:([leetcode -- backtracking] 10. Regular Expression Matching)