题目
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).
解法一: 42.17% 95.20%
动态规划,从上到下。代码:
class Solution {
public:
bool isMatch(string s, string p) {
return match(s,p,s.size()-1,p.size()-1);
}
bool match(string& s,string& p,int si,int pi){
if(si==-1&&pi==-1) return true;
if(pi==-1) return false;
if(si==-1){
if(p[pi]=='*') return match(s,p,si,pi-2);
else return false;
}else{
if(s[si]==p[pi]||p[pi]=='.') return match(s,p,si-1,pi-1);
else if(p[pi]=='*'){
if(p[pi-1]==s[si]||p[pi-1]=='.')
return match(s,p,si,pi-2)||match(s,p,si-1,pi-2)||match(s,p,si-1,pi);
else
return match(s,p,si,pi-2);
}else
return false;
}
}
};
解法二:99.84% 93.23%
动态规划,从低往上。用dp[i+1][j+1]表示s[...i]与p[...j]能否匹配上,状态转移表达式分三种情况:
(1)s[i]==p[j]||p[j]=='.' -->dp[i-1][j-1];
(2)p[j]=='*':
- p[j-1]!=s[i]&&p[j-1]!='.' -->dp[i][j-2];
- else -->dp[i][j-2]||dp[i][j-1]||dp[i-1][j]
(3)else -->0
代码:
class Solution {
public:
bool isMatch(string s, string p) {
//s[i]==p[j]||p[j]=='.' -->dp[i-1][j-1];
//p[j]=='*'
//p[j-1]!=s[i]&&p[j-1]!='.' -->dp[i][j-2];
//else -->dp[i][j-2]||dp[i][j-1]||dp[i-1][j]
//else -->0
bool dp[s.size()+1][p.size()+1];
dp[0][0]=true;
for(int i=0;i<s.size();++i)
dp[i+1][0]=false;
for(int j=0;j<p.size();++j){
dp[0][j + 1] = j > 0 && '*' == p[j] && dp[0][j - 1];
}
for(int i=0;i<s.size();++i){
for(int j=0;j<p.size();++j){
if(p[j]!='*')
dp[i+1][j+1]=dp[i][j]&&('.' == p[j] || s[i] == p[j]);
else{
if('.'!= p[j-1]&&s[i]!=p[j-1])
dp[i+1][j+1]=dp[i+1][j-1];
else
dp[i+1][j+1]=dp[i+1][j-1]||dp[i+1][j]||dp[i][j+1];
}
}
}
return dp[s.size()][p.size()];
}
};