题目:Implement wildcard pattern matching with support for '?' and '*'.
'?' 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
思路:
贪心算法。
首先使用指针会方便很多,如果p=s或者p=?,那么后移,如果p=*,这个时候记住p和s的位置,continue,机关下次可能依然有
p=s或者p=?,p=*等情况,但只有接下来没有这些特殊情况后,p重新回到最近的start+1的地方,因为它能够代替许多长度的字符。
当然,最后还需要考虑是否存在s结束,p还没有结束的情况。如果有,p一直后移。
代码:
class Solution1 {
public:
bool isMatch(string s, string p) {
char *ss=&s[0];char *pp=&p[0];
char *start=NULL,*rs=NULL;
while(*ss!='\0'){
if(*ss==*pp||*pp=='?'){
ss++;pp++;
continue;
}
if(*pp=='*'){
start=pp;
pp++;//这个时候从下一位开始匹配,因为之前的p可以匹配0位的,1位的....
rs=ss;
continue;
}
//上面两种情况都不符合,那就让之前的*来匹配
if(start!=nullptr){
pp=start+1;
ss=rs;//从第0位开始匹配
rs++;
continue;
}
return false;
}
while(*pp=='*'){
pp++;
}
return *pp=='\0';
}
};
class Solution2 {
//https://leetcode.com/problems/wildcard-matching/
//动态规划
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
vector<vector<bool> >dp(m+1,vector<bool>(n+1,false));
dp[0][0]=true;
// dp[i][j] 代表s[0..i-1]与p[0...j-1]是否匹配
for(int i=1;i<=n;i++){
dp[0][i] = p[i-1]=='*' && dp[0][i-1];
}//这个时候i=0,还没有进入s,只有 p[j-1]=='*' 且dp[0][j-1] 才行
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(p[j-1]=='*'){
dp[i][j] = dp[i-1][j]||dp[i][j-1] ;
//按照道理,应该是
//dp[i][j] = dp[i][j-1]||dp[i-1][j-1]||dp[i-2][j-1]||dp[i-3][j-1] ||....||dp[0][j-1]
// 匹配0个 匹配1个 匹配2个 匹配3个
//dp[i-1][j]= dp[i-1][j-1]||dp[i-2][j-1]||dp[i-3][j-1] ||....||dp[0][j-1]
// 匹配0个 匹配1个 匹配2个
//所以dp[i][j] = dp[i-1][j]||dp[i][j-1]
//只是每次迭代其实dp[i-1][j-1]已经把后面那部分算过了。
}
else if(p[j-1]=='?'||s[i-1]==p[j-1]){
dp[i][j]=dp[i-1][j-1];
}
}
}
return dp[m][n];
}
};