leetcode 44. 通配符匹配
1)动态规划法:110ms 30MB
class Solution { public: bool isMatch(string s, string p) { //动态规划法: //dp[0][0]=1,dp[i][j]表示s前i个字符匹配p前j个字符; //dp[i][0]=0,p为空不可能匹配s, //dp[0][j]=1,当p的前j个都为*时成立,否则为0; //dp[i-1][j-1]==1 && s[i]==p[j]||p[j]=='?' ==> dp[i][j]=1 //dp[i-1][j]==1 ||dp[i][j-1]==1 && p[j]=='*' ==> dp[i][j]=1; int ls=s.size(),lp=p.size(); vector<vector<int>> dp(ls+1,vector(lp+1,0)); dp[0][0]=1; for(int i=1;i<=ls;i++) dp[i][0]=0; int flag=1; for(int j=1;j<=lp;j++){ if(p[j-1]!='*') flag=0; dp[0][j]=flag; } for(int i=1;i<=ls;i++){ for(int j=1;j<=lp;j++){ if(s[i-1]==p[j-1] || p[j-1]=='?') dp[i][j]=dp[i-1][j-1]; else if(p[j-1]=='*') dp[i][j]=dp[i-1][j]||dp[i][j-1]; } } return dp[ls][lp]; } };
2)双指针法:4ms 8MB
class Solution { public: bool isMatch(string s, string p) { //双指针法 /* 1. 判断是否相等或p[j]为?,是则同时递增 2. s[i]!=p[j] 判断p[j]是否为*,如为*,记录当前*位置start,记录*匹配的字符串结尾为match=i,为开区间,不包括match;可知此时i应该保持原值,j自增1; 3. s[i]!=p[j] 且p[j]!=*, 判断是否之前有*(start是否为-1),如果有*,则将*匹配字符串向后延长一位,j指向*之后一位;此处没有j<p.size(),因为在*的情况下是可能会出现j==p.size()但符合要求的情况的,比如“aa”,"*",匹配完第一个字符后i=0,j=1,此时j==p.size()==1,但是依然可以; 4. 以上均不满足则不可能匹配; */ int i=0,j=0,start=-1,match=0; while(i<s.size()){ if( j<p.size() && (s[i]==p[j] || p[j]=='?') ){ i++;j++; }else if( j<p.size() && p[j]=='*'){ start=j; match=i; j++; }else if( start!=-1){ match+=1; j=start+1; i=match; }else{ return false; } } while(j<p.size()){ if(p[j]!='*') return false; j++; } return true; } };