Given an input string (s
) and a pattern (p
), 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).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
.
Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Example 4:
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
Example 5:
Input:
s = "mississippi"
p = "mis*is*p*."
Output: false
题解
一开始搞了个dp,很慢:
1 class Solution { 2 public: 3 bool match[1005][1005]; 4 bool equal(char a, char b) { 5 if (a == '.')return true; 6 else return a == b; 7 } 8 bool isMatch(string s, string p) { 9 memset(match, 0, sizeof(match)); 10 string _p = p; 11 bool isstar[1005] = { false }; 12 int pt = 0; 13 for (int i = 0; p[i]; i++) { 14 _p[pt++] = p[i]; 15 if (p[i + 1] == '*') { 16 i++; 17 isstar[pt - 1] = true; 18 } 19 } 20 match[0][0] = true; 21 for(int i=0;isstar[i];i++)match[i+1][0] = true; 22 for(int i=1;i<=pt;i++) 23 for (int j=1; s[j-1]; j++) { 24 for (int k = 1; k <= i; k++) { 25 if (match[k][j])continue; 26 if (match[k - 1][j - 1] && equal(_p[k - 1], s[j - 1])) { 27 match[k][j] = true; 28 for (int t = k+1; isstar[t - 1]; t++) 29 match[t][j] = true; 30 } 31 } 32 if (match[i][j - 1] && isstar[i - 1] && equal(_p[i - 1], s[j - 1])) { 33 match[i][j] = true; 34 for (int t = i + 1; isstar[t - 1]; t++) 35 match[t][j] = true; 36 } 37 } 38 return match[pt][s.size()]; 39 } 40 };
后来弄了个递归果然更慢了
1 class Solution { 2 public: 3 bool isMatch(string s,string p) { 4 if (p == "")return s == ""; 5 if (s == ""&&p.size() <= 1)return false; 6 if (s == ""&&p[1] != '*')return false; 7 if (p.size()>=2&&p[1] == '*') { 8 int i, l = s.size(); 9 bool ans = isMatch(s, p.substr(2, p.size() - 2)); 10 for (i = 0; (s[i] == p[0]|| p[0] == '.') && i < l; i++) 11 ans=ans||isMatch(s.substr(i+1,s.size()-i-1), p.substr(2,p.size()-2)); 12 return ans; 13 } 14 if(p[0] == '.'||p[0] == s[0])return isMatch(s.substr(1, s.size() - 1), p.substr(1, p.size() - 1)); 15 return false; 16 } 17 };
唉……好吧,又回到dp……是刚刚那个dp太混乱了
1 class Solution { 2 public: 3 bool isMatch(string s,string p) { 4 int m = s.size(), n = p.size(); 5 vector<vector<bool>>dp(m + 1, vector<bool>(n + 1, false)); 6 dp[0][0] = true; 7 for (int i = 0; i <= m; i++) { 8 for (int j = 1; j <= n; j++) { 9 if (j > 1 && p[j - 1] == '*') 10 dp[i][j] = dp[i][j - 2] || 11 (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]); 12 else 13 dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.'); 14 } 15 } 16 return dp[m][n]; 17 } 18 };