小旭讲解 LeetCode 10. Regular Expression Matching

Problem

Given an input string ( s ) and a pattern ( p ), implement regular expression matching with support for  '.' and  '*' .

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s  could be empty and contains only lowercase letters  a-z .
  • p  could be empty and contains only lowercase letters  a-z , and characters like  .  or  * .

Example 1:

<strong>Input:</strong>
s = "aa"
p = "a"
<strong>Output:</strong> false
<strong>Explanation:</strong> "a" does not match the entire string "aa".

Example 2:

<strong>Input:</strong>
s = "aa"
p = "a*"
<strong>Output:</strong> true
<strong>Explanation:</strong> '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:

<strong>Input:</strong>
s = "ab"
p = ".*"
<strong>Output:</strong> true
<strong>Explanation:</strong> ".*" means "zero or more (*) of any character (.)".

Example 4:

<strong>Input:</strong>
s = "aab"
p = "c*a*b"
<strong>Output:</strong> true
<strong>Explanation:</strong> c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".

Example 5:

<strong>Input:</strong>
s = "mississippi"
p = "mis*is*p*."
<strong>Output:</strong> false

题目

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。

  • ‘.’ 匹配任意单个字符
  • ‘*’ 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

Video Explaination

B站视频源(待审核)

YouTube视频源

Explaination

能否用动态规划的方式求解?

确认问题能否用动态规划的方式求解——即分析问题能否划分成若干个 重叠的子问题 ,并且能够 层层递进的求解 (最优子结构)。

其中要体现两个动态规划问题的性质:

  • 重叠子问题性质
  • 最优子结构性质

分类(按照状态空间递进的方式,仅仅提及两种)

  • 线性DP
    • 状态空间以线性的方式进行递推求解
  • 区间DP
    • 状态空间以“区间长度”的方式进行递推求解(可参考题目Stone Game II)

本题属于线性DP问题。

Code

Dynamic Programming(线性DP)

class Solution {
public:
    bool isMatch(string s, string p) {
        vector<vector<int>> dp(s.size() + 1, vector<int>(p.size() + 1, 0));
        dp[s.size()][p.size()] = 1;
        for (int i = s.size(); i >= 0; --i) {
            for (int j = p.size() - 1; j >= 0; --j) {
                bool first_match = i < s.size() && (s[i] == p[j] || p[j] == '.');
                if (j < p.size() - 1 && p[j + 1] == '*') {
                    dp[i][j] = (first_match && (dp[i + 1][j] || dp[i][j + 2])) || (!first_match && (dp[i][j + 2]));
                } else {
                    dp[i][j] = first_match && dp[i + 1][j + 1];
                }
            }
        }
        return dp[0][0];
    }
};

Comlexity Analysis

Time Complexity: O(M * N) M is the length of string s, N is the length of string p.

Space Complexity:

O(M * N)

Recursive

class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.empty()) return s.empty();
        bool first_match = !s.empty() && (s[0] == p[0] || p[0] == '.');
        if (p.length() >= 2 && p[1] == '*') {
            return isMatch(s, p.substr(2)) || (first_match && isMatch(s.substr(1), p));
        } else {
            return first_match && isMatch(s.substr(1), p.substr(1));
        }
    }
};

Problem: https://leetcode-cn.com/problems/regular-expression-matching

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章