题目链接
解法——动态规划()
我们发现本题的字符串匹配可以采取由起点开始逐渐扩大匹配规模的方式,因此可以采用动态规划的状态转移方程求解。
-
设状态表示字符串
s的前个字符和字符串p的前个字符能否匹配。这里假设s和p的下标均从1开始。初始时,。 -
此时我们回到题目上来。由题意可知在字符串
p中,.可以替代任何一个字符;而*可以和前一个字符搭档,让前一个字符的数量变为0或任意多个。注意,当后面一个字符是*的时候,当前字符应该先跳过不处理,与*组成搭档后一并处理。所以我们分为两种情况:- 后面一个字符不是
*的时候,则当前有 - 当前字符是
*的时候,若,可以从转移,表示丢弃这一次的*和上一个字符;若且表示这个字符可以利用这个*,则可以从转移,表示利用*。
- 后面一个字符不是
-
初始状态为,循环遍历从0到;从1到。因为可能是有意义的,需要被转移更新。
-
最终答案是。
代码如下:
class Solution {
public:
bool isMatch(string s, string p) {
int n = s.size(), m = p.size();
s = ' ' + s, p = ' ' + p;
vector <vector<bool>> f(n + 1, vector<bool>(m + 1)); //相当于新建一个(n, m)的二维数组
f[0][0] = true;
for (int i = 0; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (j + 1 <= m && p[j + 1] == '*') continue;
if (i && p[j] != '*') {
f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');
} else if (p[j] == '*') {
f[i][j] = f[i][j - 2] || i && f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');
}
}
return f[n][m];
}
};