原题地址(困难)

方法1—递归

思路

开始我想到的是递归,改了多次以后,还是超时。。。。
不过写的也挺不容易的,还是把这个方法贴出来吧。

思路流程如下: 10. 正则表达式匹配 - 图1

代码

  1. class Solution {
  2. public:
  3. bool isMatch(string s, string p) {
  4. int si = 0, pi = 0, n = s.size(), m = p.size();
  5. return dfs(s, p, si, pi, n, m);
  6. }
  7. bool dfs(string s, string p, int si, int pi, int n, int m ) {
  8. // 边界条件
  9. if(si < n && pi >= m) return false;
  10. else if(si >= n){
  11. while(pi + 1 < m && p[pi+1] == '*')
  12. pi += 2;
  13. if(pi < m) return false;
  14. else return true;
  15. }
  16. // 递归
  17. if(p[pi] != '*' && p[pi] != '.'){ // p[pi]是字母
  18. if(pi+1 >= m || (pi+1 < m && p[pi+1] != '*')) {
  19. if(p[pi] != s[si]) return false;
  20. else return dfs(s, p, si+1, pi+1, n, m);
  21. }
  22. else { // 字母后跟* c* 可能匹配:{null, c, cc, ccc, ...}
  23. bool res = dfs(s, p, si, pi+2, n, m); // 把null单拿出来
  24. // 再匹配其他的情况
  25. char tmp = p[pi];
  26. while(si < n && s[si] == tmp){
  27. res |= dfs(s, p, si+1, pi+2, n, m);
  28. si++;
  29. }
  30. return res;
  31. }
  32. }
  33. else if(p[pi] == '.') { // p[pi]是.
  34. if(pi+1 >= m || (pi+1 < m && p[pi+1] != '*')) // 单点匹配,后无*
  35. return dfs(s, p, si+1, pi+1, n, m);
  36. else { // .*可匹配任意
  37. bool res = dfs(s, p, si, pi+2, n, m);
  38. while(si < n) {
  39. res |= dfs(s, p, si+1, pi+2, n, m);
  40. si++;
  41. }
  42. return res;
  43. }
  44. }
  45. return false;
  46. }
  47. };

方法2—动态规划

思路

动态规划才是正解。。。。
不过大体思路和递归一样,也是分情况讨论。
dp[i][j] 表示s的前i个字符和p的前j个字符是否匹配
**
直接看的官方题解

10. 正则表达式匹配 - 图2

代码

  1. class Solution {
  2. public:
  3. bool isMatch(string s, string p) {
  4. int m = s.size();
  5. int n = p.size();
  6. auto matches = [&](int i, int j) {
  7. if (i == 0) {
  8. return false;
  9. }
  10. if (p[j - 1] == '.') {
  11. return true;
  12. }
  13. return s[i - 1] == p[j - 1];
  14. };
  15. vector<vector<int>> f(m + 1, vector<int>(n + 1));
  16. f[0][0] = true;
  17. for (int i = 0; i <= m; ++i) {
  18. for (int j = 1; j <= n; ++j) {
  19. if (p[j - 1] == '*') {
  20. f[i][j] |= f[i][j - 2];
  21. if (matches(i, j - 1)) {
  22. f[i][j] |= f[i - 1][j];
  23. }
  24. }
  25. else {
  26. if (matches(i, j)) {
  27. f[i][j] |= f[i - 1][j - 1];
  28. }
  29. }
  30. }
  31. }
  32. return f[m][n];
  33. }
  34. };

时空复杂度

空间复杂度O(NM)
时间复杂度O(N
M)