题目链接:https://leetcode-cn.com/problems/regular-expression-matching/
解题步骤:
- 使用动态规划进行求解
- 定义状态:dp[ i ][ j ]表示 s 的前 i 个字符是否能被 p 的前 j 个字符匹配
- 转移方程:从已经求出来的dp[ i - 1 ][ j - 1 ]入手,考虑s[ i ]、p[ j ]的各种情况
- 如果s[ i - 1 ] == p[ j - 1 ] || p[ j - 1 ] == ‘.’,dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ]
- 如果p[ j - 1 ] == ‘*’,因为’*'表示匹配零个或多个前面的那一个元素
- 当’*'匹配零个时,dp[ i ][ j ] = dp[ i ][ j - 2 ]
- 当’*'匹配多个时,即s[ i - 1] == p[ j - 2] || p[ j - 2 ] == ‘.’,dp[ i ][ j ] = dp[ i - 1][ j ]
C++实现:
class Solution {
public:
bool matches(string& s, string& p, int i, int j) {
if (i == 0)
return false;
else if (p[j-1] == '.')
return true;
else
return s[i-1] == p[j-1];
}
bool isMatch(string s, string p) {
int slen = s.size();
int plen = p.size();
vector<vector<int>> dp(slen+1, vector<int>(plen+1));
dp[0][0] = true;
for (int i = 0; i <= slen; i++) {
for (int j = 1; j <= plen; j++) {
if (p[j-1] == '*') {
dp[i][j] |= dp[i][j-2];
if (matches(s, p, i, j-1)) {
dp[i][j] |= dp[i-1][j];
}
}
else {
if (matches(s, p, i, j)) {
dp[i][j] |= dp[i-1][j-1];
}
}
}
}
return dp[slen][plen];
}
};
C语言的不同解法
bool isMatch(char * s, char * p){
if (*p == '\0') return *s == '\0';
bool first = *s != '\0' && (*p == *s || *p == '.');
if (strlen(p) >= 2 && *(p+1) == '*')
{
return isMatch(s,p+2) || (first && isMatch(s+1, p));
}
else
return first && isMatch(s+1, p+1);
}