题目
请实现一个函数用来匹配包括’.’和’‘的正则表达式。
模式中的字符’.’表示任意一个字符,而’
‘表示它前面的字符可以出现任意次(含0次)。
在本题中,匹配是指字符串的所有字符匹配整个模式。
例如,字符串”aaa”与模式”a.a”和”abaca”匹配,但是与”aa.a”和”aba”均不匹配。
样例
输入:
s=”aa”
p=”a

输出:true

解法一:模拟

需要注意一下的处理
大循环结束后,字符串s必须得匹配完,模式串可以不匹配到结束,但是这种情况要求下一位必须得是
(测试得出,最初以为模式串也得匹配完)
时间复杂度O(n+m),空间复杂度O(1)

  1. class Solution {
  2. public:
  3. bool isMatch(string s, string p) {
  4. int i = 0, j = 0;
  5. while (i < s.size() && j < p.size()) {
  6. if (s[i] == p[j] || p[j] == '.') {
  7. i++;
  8. if (!(j + 1 < p.size() && p[j + 1] == '*')) {
  9. j++;
  10. }
  11. }
  12. else if (p[j] == '*') {
  13. j++;
  14. }
  15. else if (j + 1 < p.size() && p[j + 1] == '*') {
  16. j++;
  17. }
  18. else {
  19. // cout << i << ' ' << j << endl;
  20. return false;
  21. }
  22. }
  23. if (i == s.size() && (j == p.size() || (p[j + 1] == '*')))
  24. return true;
  25. // cout << i << ' ' << s.size() << ' ' << j << ' ' << p.size() << endl;
  26. return false;
  27. }
  28. };

解法二:动态规划

字符串匹配之类问题都可以用动态规划去做
f[i][j]表示字符串s从i到结尾,模式串p从j到结尾的匹配情况

  • p[j+1]不是*
    • (s[i] == p[j] || p[j] == ‘.’) && f[i+1][j+1]
  • p[j+1]是*
    • p[j]零次匹配:考察f[i][j+2]
    • p[j]多次匹配:(s[i] == p[j] || p[j] == ‘.’) && 考察f[i+1][j]

时间复杂度O(mn),空间复杂度O(mn)

  1. class Solution {
  2. public:
  3. int n, m;
  4. vector<vector<int>> f;
  5. bool isMatch(string s, string p) {
  6. n = s.size(), m = p.size();
  7. f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
  8. return dp(0, 0, s, p);
  9. }
  10. bool dp(int x, int y, const string &s, const string &p) {
  11. if (f[x][y] != -1) return f[x][y];
  12. if (y == m) {
  13. return f[x][y] = x == n;
  14. }
  15. bool first_match = x < n && (s[x] == p[y] || p[y] == '.');
  16. if (y + 1 < m && p[y + 1] == '*') {
  17. f[x][y] = dp(x, y + 2, s, p) || first_match && dp(x + 1, y, s, p);
  18. }
  19. else {
  20. f[x][y] = first_match && dp(x + 1, y + 1, s, p);
  21. }
  22. return f[x][y];
  23. }
  24. };