剑指offer52_正则表达式匹配_题解

正则表达式匹配

题目描述

请实现一个函数用来匹配包括'.'和''的正则表达式。模式中的字符'.'表示任意一个字符,而''表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配

示例1

输入

"aaa","a*a"

返回值

true

分析

方案一:递归

算法思想:

  1. 递归函数功能:\(match(s,p)\)表示 \(p\) 是否可以匹配 \(s\)
  2. 递归终止条件:当 \(p\) 为空时,若 \(s\) 也为空,表明匹配正确;若 \(s\) 不为空,则表明不能正确匹配
  3. 递归逻辑:
    1. 如果 \(p[1]==*\),表明 \(p[0]\) 对应的字符可以重复 \(0\) 次或者多次
      1. 重复 \(0\) 次,则继续匹配 \(s[0...m]\)\(p[2...n]\)
      2. 重复多次,继续匹配 \(s[1...m]\)\(p[0...n]\)
    2. 如果 \(p[0]==s[0]\)\(p[0]≠*\),则匹配 \(s[1...m]\)\(p[1...n]\)
    3. 否则返回 \(false\)

代码

/**
1.时间复杂度:小于O(mn)
2.空间复杂度:O(m)、O(n)和递归栈的空间
**/
class Solution
{
public:
    bool match(string s, string p)
    {
        if (p.empty())
            return s.empty();
        bool first_match = !s.empty() && (s[0] == p[0] || p[0] == '.');
        if (p.size() >= 2 && p[1] == '*')
            return match(s, p.substr(2)) || (first_match && match(s.substr(1), p));
        else
            return first_match && match(s.substr(1), p.substr(1));
    }
    bool match(char *str, char *pattern)
    {
        string s(str), p(pattern);
        return match(s, p);
    }
};

方案二:动态规划

算法思想:

img

代码

/**
1.时间复杂度:O(mn)
m和n分别是字符串s和p的长度。
2.空间复杂度:O(mn)
存储所有状态使用的空间
**/
class Solution
{
public:
    bool first_match(string s, string p, int i, int j)
    {
        return s[i] == p[j] || p[j] == '.';
    }
    bool match(char *str, char *pattern)
    {
        string s(str), p(pattern);
        int ls = s.size(), lp = p.size();
        vector<vector<bool>> dp(ls + 1, vector<bool>(lp + 1));
        dp[0][0] = true;
        for (int j = 2; j <= lp; j++)
            dp[0][j] = (p[j - 1] == '*' && dp[0][j - 2]);
        for (int i = 0; i < ls; i++)
        {
            for (int j = 0; j < lp; j++)
            {
                if (p[j] == '*')
                {
                    dp[i + 1][j + 1] = dp[i + 1][j - 1] || first_match(s, p, i, j - 1) && dp[i][j + 1];
                }
                else
                {
                    dp[i + 1][j + 1] = first_match(s, p, i, j) && dp[i][j];
                }
            }
        }
        return dp[ls][lp];
    }
};

posted @ 2021-02-19 20:08  RiverCold  阅读(38)  评论(0编辑  收藏  举报