![](https://cdn.jsdelivr.net/gh/xiaok0707/MyPhotos@master/img/20200825231923.png)
DP
令 dp[i][j]
表示 s[0...i-1]
和 p[0...j-1]
是否匹配,然后对 dp[i][j]
进行分类讨论:
- 若
p[j-1]
是普通字母,则p[j-1]=s[i-1]
且s[0...i-2]
和p[0...j-2]
匹配即dp[i-1][j-1]=true
时,dp[i][j]=true
. - 若
p[j-1]='.'
,则无论s[i-1]
是什么p[j-1]
都可以与其匹配,所以只需要dp[i-1][j-1]=true
时,dp[i][j]=true
. - 若
p[j-1]='*'
,说明p[j-2]
这个字符出现了 0 次或多次.- 若
p[j-2]
出现了 0 次,那么当dp[i][j-2]=true
时,dp[i][j]=true
. - 若
p[j-2]
出现次数 >0 次,令ch=p[j-2]
说明p
的末尾有若干个相同字符ch
,只有s[i-1]=ch
且dp[i-1][j]=true
时,dp[i][j]=true
. 具体来说,让s[i-1]
与最后一个ch
进行匹配,这样一来前面的字符中未匹配的ch
出现的次数为 0 次或多次,又变成了一个相同的子问题,只需要考虑dp[i-1][j]=true
是否成立即可.
- 若
class Solution {
public:
bool isMatch(string s, string p) {
int n=s.length(),m=p.length();
vector<vector<bool> > dp(n+1,vector<bool>(m+1,false));
dp[0][0]=true;
for(int i=0;i<=n;++i){
for(int j=1;j<=m;++j){
if(p[j-1]!='*'){
if(i-1>=0 && (p[j-1]=='.' || s[i-1]==p[j-1])) dp[i][j]=dp[i-1][j-1];
}
else{
dp[i][j]=dp[i][j-2];
if(i-1>=0 && (p[j-2]=='.' || s[i-1]==p[j-2])) dp[i][j]=dp[i][j] || dp[i-1][j];
}
}
}
return dp[n][m];
}
};
个人 LeetCode 代码仓库地址:MyLeetCode,记录刷题成长之路,欢迎各位小伙伴们多多 star ~