请实现一个函数用来匹配包括'.'
和'*'
的正则表达式。
模式中的字符'.'
表示任意一个字符,而'*'
表示它前面的字符可以出现任意次(含0次)。
例如,字符串"aaa"
与模式"a.a"
和"ab*ac*a"
匹配,但是与"aa.a"
和"ab*a"
均不匹配。
class Solution{
public:
bool isMatch(string s, string p){
}
};
题目并没有给出数据范围
一篇良心题解
设令 (s) 长度为 (n) , (p) 长度为 (m) , (f[i][j]) 表示 (p[j,m]) 能否匹配 (s[i,n])
(1.) 如果 (p[j+1]) (!=) '(*)' , 则 (f[i][j]) 为真当且仅当 (s[i]) 可以和 (p[j]) 匹配 , 且 (f[i+1][j+1]) 为真 .
(2.) 如果 (p[j+1]) (==) '(*)' , 则 (f[i][j]) 有以下两种情况可以为真 :
"(*)" 代表 (0) 个 (p[j]) , 等价于 (f[i][j+2]) 为真 ;
"(*)" 代表若干个 (p[j]) , 等价于 $f[i+1][j] $ 为真而且 (s[i]) 可以和 (p[j]) 匹配
然后就可以用记忆化了 , 一共 (nm) 个状态 , 时间复杂度 (O(nm)) .
class Solution{
public:
vector<vector<int>> f;
int n, m;
bool isMatch(string s, string p){
n = s.size(), m = p.size();
f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
// f = n+1个 ((m+1个-1)组成的vector)
return dp(0, 0, s, p);
}
inline bool dp(int x, int y, string& s, string& p){
if(x > n || y > m) return 0;
if(f[x][y] != -1) return f[x][y];
if(y == m)
return f[x][y] = (x ==n);
bool now_match = ((s[x] == p[y]) || (p[y] =='.'));
bool ans;
if(p[y + 1] == '*')
ans = dp(x, y + 2, s, p) || (now_match && dp(x + 1, y, s, p));
else
ans = now_match && dp(x + 1, y + 1, s, p);
return f[x][y] = ans;
}
};
一道锻炼思维的好题 , (DP) 思维最能体现一个人的水平 .