LeetCode 10 Regular Expression Matching (C++, Python)
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
Solution C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class Solution { public: bool isMatch(string s, string p) { if (s == p) return true; if (p.empty()) return false; const int M = s.length(); const int N = p.length(); vector<vector<char>> dp(M + 1, vector<char>(N + 1, false)); dp[M][N] = true; for (int j = N - 1; j >= 0; j -= 2) { if (dp[M][j + 1] == false) break; if (j == 0) { dp[M][j] = false; continue; } if (p[j] == '*') { dp[M][j] = false; dp[M][j - 1] = true; } } for (int i = M - 1; i >= 0; -- i) { if (s[i] == p[N - 1] || p[N - 1] == '.') dp[i][N - 1] = dp[i + 1][N]; } for (int i = M - 1; i >= 0; -- i) { for (int j = N - 2; j >= 0; -- j) { if (p[j] == '.' && p[j + 1] == '*') { dp[i][j] = dp[i][j + 2] || dp[i + 1][j]; } else if (p[j + 1] == '*') { dp[i][j] = dp[i][j + 2] || ((s[i] == p[j]) && dp[i + 1][j]); } else if (s[i] == p[j] || p[j] == '.') { dp[i][j] = dp[i + 1][j + 1]; } } } return dp[0][0]; } }; |
Solution Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Solution: def isIntMatch(self, s, p, cache): if (s, p) in cache: return cache[(s, p)] if s == p: cache[(s, p)] = True return True if not p: cache[(s, p)] = False return False if not s: for i in range(0, len(p), 2): if (i + 1) == len(p): cache[(s, p)] = False return False if p[i + 1] != '*': cache[(s, p)] = False return False cache[(s, p)] = True return True if len(p) > 1: if p[:2] == '.*': ret = self.isIntMatch(s, p[2:], cache) or self.isIntMatch(s[1:], p, cache) cache[(s, p)] = ret return ret if p[1] == '*': ret = self.isIntMatch(s, p[2:], cache) or (s[0] == p[0] and self.isIntMatch(s[1:], p, cache)) cache[(s, p)] = ret return ret if p[0] == s[0] or p[0] == '.': ret = self.isIntMatch(s[1:], p[1:], cache) cache[(s, p)] = ret return ret cache[(s, p)] = False return False # @param {string} s # @param {string} p # @return {boolean} def isMatch(self, s, p): cache = {} return self.isIntMatch(s, p, cache) |