题目链接:
https://leetcode-cn.com/problems/regular-expression-matching/
困难度: 困难
10. 正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一
个支持 '.' 和 '*' 的正则表达式匹配。'.' 匹配任
意单个字符'*' 匹配零个或多个前面的那一个元素所谓
匹配,是要涵盖整个字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符
和 *。
好难 不会 好菜
一点思路都没有 看的解析 方法动态规划 但是不会找状态转移公式
f[i][j]: 表示s的前i个字符与p中的前j个字符是否能够匹配
f[0][0] 空字符串 默认匹配
对于 f[i][j] 的情况共有两种大情况
A. 对于 p 若 p[j] != ‘*’ 很明显只需要比较 s[i]==p[j] 若为真 则 f[i][j] = f[i-1][j-1], 若为假 返回false
B 其他情况有两种:
-
s[i],p[j−1] 匹配
f[i][j] = f[i-1][j] 或者 f[i][j]=f[i][j-2]f[i][j] = f[i-1][j] 代表的情况为 多次匹配 (即使用*)
f[i][j]=f[i][j-2] 代表的情况为 (*取0 即忽略前面数字和* 使其为空) -
s[i],p[j−1] 不匹配
f[i][j]=f[i][j-2] 跳过匹配
在分析一下 无论 s[i],p[j−1]匹配与否 f[i][j]=f[i][j-2] 都应该在进行判断
若匹配 则 f[i][j] = f[i-1][j]
class Solution {
public:
bool isMatch(string s, string p) {
int m=s.size();
int n=p.size();
auto matches= [&](int i,int j){
if (i==0){
return false;
}
if (p[j-1]=='.'){
return true;
}
return s[i - 1] == p[j - 1];
};
vector<vector<int>> f(m + 1, vector<int>(n + 1));
f[0][0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (p[j-1]=='*'){
// 对应 p[j] == '*'
// matches(i, j - 1)无论能否匹配
// f[i][j] |= f[i][j - 2]都会存在
// 为空 或 跳过
f[i][j] |= f[i][j - 2];
if (matches(i, j - 1)) {
// 匹配 使用组合
f[i][j] |= f[i - 1][j];
}
}else{
// 对应 p[j] != '*'
if (matches(i, j)) {
f[i][j] |= f[i - 1][j - 1];
}
}
}
}
return f[m][n];
}
};
还是不太懂 有时间还要再看!!!