y总题解写的很好,这里提醒y总没说的地方:1.在匹配“*”的时候,要么*就当不存在,即f[i][j+2]成功就行,要么*
当做重复过了几次,究竟重复了几次呢?
p[j]和s[i+1]匹配,则重复了一次,跳转到f[i+1][j],如果p[j]和s[i+2]匹配,又重复了一次,以此类推....
2.边界条件。样例有个“aa”和“a*”匹配的,最后一个符号是“*”很容易边界条件出错,因为j+2就是空白了。
于是选择在s和p的末尾加上相同的字符让他们匹配来凑数,这样边界条件写起来简单一些。
我觉得逆向的递推比正向的递推还有记忆化搜索更加简单一些,就这样写了,有问题请指正,大家加油吧!
C++ 代码
class Solution {
public:
bool isMatch(string s, string p) {
int f[500][500];
s=s+' ';
p=p+' ';
int n=s.size();
int m=p.size();
f[n][m]=1;
for(int i=n-1;i>=0;i--)
{
for(int j=m-1;j>=0;j--)
{
if(p[j]!='.'&&p[j]!='*')
f[i][j]=f[i+1][j+1]&&s[i]==p[j];
if(p[j]=='.')
f[i][j]=f[i+1][j+1];
if(p[j+1]=='*')
f[i][j]=f[i][j+2]||(f[i+1][j]&&(s[i]==p[j]||p[j]=='.'));
}
}
return f[0][0];
}
};
```