解题思路:首先很明显字符串的匹配适合动态规划,所以建立dp[i][j]表示s的前i个字符与p中的前j个字符是否能够匹配。然后就是判断各种情况。笔者在写的时候情况考虑不全导致没有通过。
"aab"
"c*a*b"
"aa"
"a*"
""
"."
所有情况的归纳:
如果 p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
如果 p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
如果 p.charAt(j) == '*':
如果 p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //in this case, a* only counts as empty
如果 p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
dp[i][j] = dp[i-1][j] //in this case, a* counts as multiple a
or dp[i][j] = dp[i][j-1] // in this case, a* counts as single a
or dp[i][j] = dp[i][j-2] // in this case, a* counts as empty
classSolution {public:bool isMatch(string s, stringp) {int m =s.size();int n =p.size();inti, j;//dp[i][j]:表示s的前i个字符与p中的前j个字符是否能够匹配。
vector> dp(m + 1, vector(n + 1));
dp[0][0] = true;//设置边界,避免越界
for (i = 1; i <= m; i++)
dp[i][0] = false;for (j = 1; j <= n; j++)if (p[j - 1] == '*')
dp[0][j] = dp[0][j - 1] || dp[0][j - 2];elsedp[0][j] = false;//正常判断
for (i = 1; i <= m; i++)for (j = 1; j <= n; j++) {if (j == 1)if (i == 1)
dp[1][1] = s[0] == p[0] || p[0] == '.';elsedp[i][j]= false;else{if (p[j-1] == '*') {if (p[j - 2] != s[i-1] && p[j - 2] != '.')
dp[i][j]= dp[i][j - 2];//如果最后一个字符不相等,则把*前的一个字符删去:aa与aab*;aabc与aab*
else if (p[j - 2] == s[i-1] || p[j - 2] == '.')
dp[i][j]= dp[i - 1][j] || dp[i][j - 1] || dp[i][j - 2];//分别是匹配多个,匹配一个,匹配0个
}else if (p[j-1] == '.')
dp[i][j]= dp[i - 1][j - 1];//如果是'.',直接判断两个字符串前i-1,j-1是否匹配。
elsedp[i][j]= s[i-1] == p[j-1] && dp[i - 1][j - 1];
}
}returndp[m][n];
}
};