题目描述
请实现一个函数用来匹配包括 ‘.’ 和 ‘*’ 的正则表达式。
模式中的字符 ‘.’ 表示任意一个字符,而 ‘*’ 表示它前面的字符可以出现任意次(含0次)。
在本题中,匹配是指字符串的所有字符匹配模式。
例如,字符串 “aaa” 与模式 “a.a” 和 “ab*ac*a” 匹配,但是与 “aa.a” 和 “ab*a” 均不匹配。
样例
Input: s = "aa" p = "a*"
Output: true
解题思路
-
描述
这种问题需要使用动态规划。
状态定义:f[i][j] 表示p从j开始到结尾,是否匹配s从i开始到结尾。
状态转移:
- 如果p[j] 为正常字符,则f[i][j] = (s[i] == p[j]) && f[i+1][j+1]。
- 如果p[j] = ‘.’,则f[i][j] =f[i+1][j+1]。
- 如果p[j + 1] = ‘*’,则f[i][j] = f[i][j+2] 或者 f[i][j] = f[i+1][j]。
-
实现代码:
string s, p; int n, m; vector<vector<int> > f; // 用作动态规划二维数组 bool dp(int x, int y) // s从x开始到结尾与p从y开始到结尾匹配 { if (f[x][y] != -1) // 如果已知匹配,则立即返回 { return f[x][y]; } if ((x == n) && (y == m)) // 边界条件 { return (f[x][y] = true); } if ((x > n) || (y > m)) // 越界返回false return false; bool isMatch = (x < n) && (s[x] == p[y] || (p[y] == '.')); // 综合1,2情况 if ((y+1 < m) && (p[y+1] == '*')) // 针对3情况 { f[x][y] = dp(x, y + 2) || dp(x + 1, y); } else { f[x][y] = isMatch && dp(x+1,y+1); } return f[x][y]; } bool isMatch(string _s, string _p) { s = _s; p = _p; n = s.size(); m = p.size(); f = vector<vector<int> >(n + 1,vector<int>(m + 1, -1)); return dp(0,0); }
-
复杂度分析
时间复杂度: O ( m n ) O(mn) O(mn)
空间复杂度: ≈ O ( m n ) \approx O(mn) ≈O(mn)
使用辅助变量vector<vector >