思路:
dp[i][j] 表示s的前i个字符和p的前j个字符是否匹配。if s[0..i-1] matches p[0..j-1]
如果 p[j - 1] != '*' 那么 dp[i][j] = dp[i - 1][j - 1] && (p[j - 1] == s[j - 1] || p[j - 1] == '.')
如果 p[j - 1] == '*'
第一种情况:p[j - 2]重复零次,也就是dp[i][j] = dp[i][j - 2]
第二种情况(难点):p[j - 2]重复>1次: dp[i][j] = (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]
初始条件:dp[0][0] = true;
dp[1..len_s-1][0] = false;
for(int i = 1; i < len_p; i++ )
dp[0][i] = j > 1 && p[j - 1] == '*' && dp[0][j - 2];
代码:
class :Solution {
public:
bool isMatch(string s, string p) {
int len_s = s.size();
int len_p = p.size();
vector<vector<bool>> dp(len_s + 1, vector<bool>(len_p + 1, false));
dp[0][0] = true;
for(int i = 1; i <= len_s; i++)
dp[i][0] = false;
for(int i = 1; i <= len_p; i++ )
dp[0][i] = i > 1 && p[i - 1] == '*' && dp[0][i - 2];
for(int i = 1; i <= len_s; i++)
for(int j = 1; j <= len_p; j++)
{
if(p[j - 1] != '*')
dp[i][j] = dp[i - 1][j - 1] && (p[j - 1] == s[i - 1] || p[j - 1] == '.');
else
dp[i][j] = dp[i][j - 2] || (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j];
}
return dp[len_s][len_p];
}
};
总结: 有一个地方因为笔误将i写成了j,查了很长时间也找不出错误所在,最后用vs2013调试才发现这个笔误!!!!!!!
所以,以后写代码一定要(最好)边想边写。而不是将思路中的代码复制。