10. Regular Expression Matching
- 递归
- 动态规划
题目
Implement regular expression matching with support for '.'
and '*'
.
‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)Some examples:
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aaa”,”aa”) → false
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
思路
递归。
- 终止条件:模式匹配完毕,字符串结束则返回 true,否则返回 false。
- 若模式的下一字符 p[j+1] != ‘*’,继续递归的条件为 s[i] == p[j] 或 p[j] == ‘.’ 且字符串未结束,否则返回 false。
- 若模式的下一字符 p[j+1] == ‘*’,则不断递归回溯 i+k,j+2(0 <= k <= len(s)-i)。
复杂性分析:
- 时间复杂度:O(n).
- 空间复杂度:O(n).【有待确定】
题解
class Solution {
public:
bool isMatch(string s, string p) {
return matchHelper(s, 0, p, 0);
}
bool matchHelper(const string& s, int i, const string& p, int j) {
if(j==p.size())
return i==s.size();
if( p[j + 1] != '*') {
if ((s[i] == p[j]) || (p[j] == '.' && i!=s.size()))
return matchHelper(s, i + 1, p, j + 1);
else
return false;
}
while((s[i] == p[j]) || (p[j] == '.' && i!=s.size())){
if(matchHelper(s, i, p, j+2))
return true;
i++;
}
return matchHelper(s, i, p, j+2);
}
};
优化
动态规划思路
- 定义:若 s[0, i) 匹配 p[0, j),则 P[i][j] 为真,否则为假。则状态方程为:
- 当 p[j - 1] != ‘*’ 且 (s[i - 1] == p[j - 1] || p[j - 1] == ‘.’)时,
P[i][j] = P[i - 1][j - 1]
。 - 当 p[j - 1] == ‘*’ 且模式不重复时,
P[i][j] = P[i][j - 2]
。 - 当 p[j - 1] == ‘*’ 且模式至少重复1次时,
P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.')
- 当 p[j - 1] != ‘*’ 且 (s[i - 1] == p[j - 1] || p[j - 1] == ‘.’)时,
代码
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size(), n = p.size();
vector<vector<bool> > dp(m+1, vector<bool>(n+1, false));
dp[0][0] = true;
for (int i = 0; i <= m; i++)
for (int j = 1; j <= n; j++)
if (p[j-1] == '*')
dp[i][j] = dp[i][j-2] ||
(i>0 && (s[i-1]==p[j-2] || p[j-2]=='.') && dp[i-1][j]);
else
dp[i][j] = i>0 && dp[i-1][j-1] && (s[i-1]==p[j-1] || p[j-1]=='.');
return dp[m][n];
}
};