Given an input string sand a pattern p, implement regular expression matching with support for '.' and '*' where:
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Example 1:
1 2 3
Input: s = "aa", p = "a" Output: false Explanation: "a" does not match the entire string "aa".
Example 2:
1 2 3
Input: s = "aa", p = "a*" Output: true Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
1 2 3
Input: s = "ab", p = ".*" Output: true Explanation: ".*" means "zero or more (*) of any character (.)".
Constraints:
1 <= s.length<= 20
1 <= p.length<= 20
s contains only lowercase English letters.
p contains only lowercase English letters, '.', and'*'.
It is guaranteed for each appearance of the character '*', there will be a previous valid character to match.
classSolution { public: string s_, p_; // the meaning of dp[i][j]: is it possible to match // when we are at index i in s and index j in p vector<vector<int>> dp;
booltraverse(int idx1, int idx2){ if (idx1 == s_.size() && idx2 == p_.size()) { returntrue; } if (idx2 == p_.size()) { returnfalse; } if (idx1 == s_.size()) { // it means we cannot match an empty string if (idx2 == p_.size() - 1 || p_[idx2 + 1] != '*') { returnfalse; } else { // try to match an empty string returntraverse(idx1, idx2 + 2); } } if (dp[idx1][idx2] != -1) { return dp[idx1][idx2]; } // the three cases we can continue: // 1. s[idx1] = p[idx2] // 2. s[idx1] != p[idx2] but p[idx2] = '.' // 3. s[idx2 + 1] = '*' if (s_[idx1] != p_[idx2] && p_[idx2] != '.' && !(idx2 + 1 < p_.size() && p_[idx2 + 1] == '*')) { returnfalse; } bool res = false; // the next item is not *, which means either the character // at idx1 and idx2 match or p_[idx2] = '.' if (idx2 == p_.size() - 1 || p_[idx2 + 1] != '*') { res = traverse(idx1 + 1, idx2 + 1); // it's a empty string match, i.e. any character with * is empty } elseif (s_[idx1] != p_[idx2] && p_[idx2] != '.') { res = traverse(idx1, idx2 + 2); } else { // we need to decide how many characters to match with * char c = s_[idx1]; res = traverse(idx1, idx2 + 2); for (int i = idx1; i < s_.size() && (s_[i] == c || p_[idx2] == '.'); i++) { res |= traverse(i + 1, idx2 + 2); if (res) { break; } } } dp[idx1][idx2] = res; return res; } };