【递归与动态规划】正则表达式匹配
https://leetcode-cn.com/problems/regular-expression-matching/
1. 递归思想
如果p 为空,s为也为空。则匹配成功。
s、p为当前字符。如果*s == *p或者 *p == '.',则当前字符是匹配的。
如果p的下一个字符串为'', 如果对s的当前字符匹配零次,则p的指针向后移动两步,继续递归;如果s == p, 并p通过''匹配s中的多个字符,则s的指针向后移动一步,继续递归。
否则,如果s和p的当前字符匹配,那么s和p的指针都向后移动一步,继续递归。
class Solution {
public:
bool isMatch(string s, string p) {
return match(s.c_str(),p.c_str());
}
bool match(const char* s, const char* p){ //
if(*p == 0) return *s == 0;
bool first_char_match = *s && (*s == *p || *p == '.');
if(*(p + 1) == '*'){
return match(s, p+2) || (first_char_match && match(++s, p));
}else{
return first_char_match && match(++s, ++p);
}
}
};
2. 通过动态规划优化
用dp[i][j]表示s[0...i-1]和p[0...j-1]是否正则匹配。
如果p[j-1]是'*',
- 如果对p[j-2]匹配0次,则dp[i][j] = dp[i][j-2]
- 如果p[j-2] == s[i-1], 并对p[j-2]匹配1次或多次,则dp[i][j] = dp[i-1][j]
如果p[j-1] == s[i-1] 或 p[j-1] == '.':
- 则p[i][j] = p[i-1][j-1]
class Solution {
public:
bool isMatch(string s, string p) {
int sSize = s.size();
int pSize = p.size();
vector<vector<int>> dp(sSize + 1, vector<int>(pSize + 1));
dp[0][0] = true;
auto match = [&](int i , int j){
return i > 0 && (p[j - 1] == '.' || s[i -1] == p[j -1]);
};
for(int i = 0; i < sSize + 1; ++i){
for(int j = 1; j < pSize + 1; ++j){
if(p[j - 1] == '*'){
dp[i][j] |= dp[i][j-2];
if(match(i, j - 1)){
dp[i][j] |= dp[i -1][j];
}
}else if(match(i, j)){
dp[i][j] |= dp[i-1][j-1];
}
}
}
return dp[sSize][pSize];
}
};