leetcode-44. Wildcard Matching
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-44. Wildcard Matching相关的知识,希望对你有一定的参考价值。
这道题和之前的那道Regular Expression Matching有点相似,第一反应是跟之前一样,用递归来做
bool doMatch(char *s,char *p) { if (*p == ‘\0‘) return *s == ‘\0‘; if(*p == ‘*‘) { while(*s!=‘\0‘)//通配符匹配0次,1次···· { if(doMatch(s,p+1)) return true; s++; } //通配符匹配完后还是无法匹配 return doMatch(s,p+1); } else { // if(*p!=*s && *p!=‘.‘) return false; // return doMatch(s+1,p+1); if (*p == *s || (*p == ‘?‘ && *s != ‘\0‘)) return doMatch(s+1, p+1); return false; } } bool isMatch(char* s, char* p) { if(*p==‘\0‘) return *s==‘\0‘; char *new_p = (char *)malloc(strlen(p)); int j=0; //先对p预处理,多个*变为一个 for(int i=0;i<strlen(p);i++) { if(i>0 && p[i]==‘*‘ && p[i-1]==‘*‘) continue; new_p[j] = p[i]; j++; } new_p[j] = ‘\0‘; return doMatch(s,new_p); }
超时了。。。这是因为出现了重复比较的情况。比如当p = "c*ab*c",s = "cddabbac",遇到第一个*时,需要用递归处理p的剩余部分"ab*c" 和s的剩余部分"ddabbac"。遇到第二个*时还需要比较剩余部分,所以需要用动态规划消除重复子问题。
dp[i][j]代表到p[i-1]和s[j-1]为止一直匹配,所以当前字符为*时dp[i][j]=dp[i-1][j]||dp[i][j-1]||dp[i-1][j-1]
当前字符为其他情况时 dp[i]pj]=dp[i-1][j-1] && (p[i-1]==‘?‘ || p[i-1]==s[j-1])
这里为了方便设初值,增加一行一列,并令dp[0][0]=true;
我们注意到dp的值只与前一行和前一列有关,所以可以将数组缩减为两行以节省空间。
class Solution { public: bool isMatch(string s, string p) { int s_len = s.length(); int p_len = p.length(); vector<vector<bool>>dp(2,vector<bool>(s_len+1,false)); dp[0][0] = 1; for(int i=1;i<=p_len;i++) { int cur=i%2; int prev=(i+1)%2; dp[cur][0]=dp[prev][0]&&p[i-1]==‘*‘; for(int j=1;j<=s_len;j++) { if(p[i-1]==‘*‘) dp[cur][j] = dp[cur][j-1] || dp[prev][j] ||dp[prev][j-1]; else dp[cur][j] = dp[prev][j-1] && (p[i-1]==‘?‘ || p[i-1]==s[j-1]); } } return dp[p_len%2][s_len]; } };
以上是关于leetcode-44. Wildcard Matching的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode 44: Wildcard Matching
leetcode-44. Wildcard Matching