'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
I implement a DP solution, but the code didn't pass all test cases of leetcode due to running over the memory limit of leetcode.My code is given as below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool helper(string s, string p, vector<vector<int> >& flag){ | |
if(flag[s.length()][p.length()]!=-1) | |
return flag[s.length()][p.length()]; | |
if(s[0]==p[0]||p[0]=='?'){ | |
return flag[s.length()-1][p.length()-1]; | |
} | |
if(p[0]=='*'){ | |
bool r0=false; | |
bool r1=false; | |
bool r2=false; | |
r0=flag[s.length()][p.length()-1]; | |
if(r0==true){ | |
flag[s.length()][p.length()]=r0; | |
return r0; | |
} | |
r1=flag[s.length()-1][p.length()]; | |
if(r1==true){ | |
flag[s.length()][p.length()]=r1; | |
return r1; | |
} | |
r2=flag[s.length()-1][p.length()-1]; | |
if(r2==true){ | |
flag[s.length()][p.length()]=r2; | |
return r2; | |
} | |
flag[s.length()][p.length()]=false; | |
return false; | |
} | |
if(s[0]!=p[0]&&p[0]!='*'&&p[0]!='?') | |
flag[s.length()][p.length()]=0; | |
return flag[s.length()][p.length()]; | |
} | |
bool isMatch(string s, string p) { | |
vector<vector<int> > flag(s.length()+1, vector<int>(p.length()+1, -1)); | |
flag[0][0]=1; | |
for(int j=1; j<=p.length(); ++j) | |
flag[0][j]=flag[0][j-1]&&(p[p.length()-j]=='?'||p[p.length()-j]=='*'); | |
for(int i=1; i<=s.length(); ++i) | |
flag[i][0]=0; | |
bool r=helper(s, p, flag); | |
return r; | |
} |
https://leetcode.com/discuss/10133/linear-runtime-and-constant-space-solution.
The method, try to match as many common characters of s and p, and when match is failed at current location, it roll back and to last '*' location, and increment pointer of s by one. It will roll back again and make the increment if the match still can not be found.
For each element in s
If *s==*p or *p == ? which means this is a match, then goes to next element s++ p++.
If p=='*', this is also a match, but one or many chars may be available, so let us save this *'s position and the matched s position.
If not match, then we check if there is a * previously showed up,
if there is no *, return false;
if there is an *, we set current p to the next element of *, and set current s to the next saved s position.
For quick reference, the code is given in below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
bool isMatch(string s, string p) { | |
int m = s.length(), n = p.length(); | |
int i = 0, j = 0, asterick = -1, match; | |
while (i < m) { | |
if (j < n && p[j] == '*') { | |
match = i; | |
asterick = j++; | |
} | |
else if (j < n && (s[i] == p[j] || p[j] == '?')) { | |
i++; | |
j++; | |
} | |
else if (asterick >= 0) { | |
i = ++match; | |
j = asterick + 1; | |
} | |
else return false; | |
} | |
while (j < n && p[j] == '*') j++; | |
return j == n; | |
} | |
}; |
No comments:
Post a Comment