题目大意:匹配字符串s和p,字符串s包含一些字母,p包含字母/'.'/'*',三种字符,'.'可以匹配一个字母,'*'可以匹配与它前面的字符相同的字符的0到多个
分析:动态规划。
状态:dp[i][j]——s的0到第i位和p的0到第j位是否匹配成功。
结果:dp[s.size()][p.size()]
状态转移方程:
1、如果s[i]==p[j]那么他们前i位和前j位是否匹配成功就依赖于前i-1和前j-1位是否匹配成功。
dp[i][j] = dp[i - 1][j - 1]
2、如果p[j]=='.' 他可以匹配s中的一个字符,所以同上dp[i][j] = dp[i - 1][j - 1];
3、如果p[j]=='*',分两种情况:
(1)如果p[j - 1]!=s[i]那么相当于p中的这个当前的a*并不能匹配上s中的字母,所以相当于空串。
dp[i][j] = dp[i][j - 2]
(2)如果p[j - 1]==s[i]或者p[j - 1]=='.'
dp[i][j] = dp[i - 1][j] a*可以匹配多个a,所以s中第i位搞定了
dp[i][j] = dp[i][j - 1] a*相当于一个a,所以去除*,当前答案依赖于i位和j-1位的匹配结果
dp[i][j] = dp[i][j - 2] a*相当于空串,去掉p串中的a*继续匹配
代码:
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size(),n = p.size();
vector<vector<bool>> dp(m + 1,vector<bool>(n + 1));
dp[0][0] = true;
for(int i = 1;i <= n;i++){
if(p[i - 1] == '*' && dp[0][i - 2])
dp[0][i] = true;
}
for(int i = 1;i <= m;i++){
for(int j = 1;j <= n;j++){
if(s[i-1] == p[j-1] || p[j-1] == '.')
dp[i][j] = dp[i - 1][j - 1];
else if(p[j-1] == '*'){
if(p[j - 2] != s[i - 1] && p[j - 2] != '.')
dp[i][j] = dp[i][j - 2];
else dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j];
}
}
}
return dp[m][n];
}
};