leetcode 正则表达式匹配 困难

Posted Wh1t3zZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 正则表达式匹配 困难相关的知识,希望对你有一定的参考价值。

 

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

 

动态规划:dp[i][j] 表示 s 串前 i 个 与 p 串前 j 个是否能够成功匹配。

状态转移方程不难:

if(s[i] == p[j] || p[j] == \'.\') dp[i][j] = dp[i - 1][j - 1];

if(p[j] == \'*\') {

  dp[i][j] = dp[i][j - 2];  // * 前面一个字符使用个数为 0

  if(s[i] == p[j - 1] || p[j - 1] == \'.\') dp[i][j] = (dp[i][j] | dp[i - 1][j] | dp[i - 1][j - 1]);  // 分别表示 * 使用的个数 >1 与 * 使用的个数 == 1.

}

 

不过需要特别注意边界的问题:如 "", "a*" 中,是能够匹配成功的。所以循环遍历是 s 串在前,就不好处理。

这里将 i 与 j 的意义调换,先循环 p 串,再循环 s 串,因为 p 串为空的情况更简单。(并且,为了处理  状态转移中下标 -1 导致越界的问题,横纵统一做一个单位偏移量)

class Solution {
public:
    bool isMatch(const string &s, const string &p) {
        vector<vector<bool>> dp(p.size() + 1, vector<bool>(s.size() + 1, false));
        dp[0][0] = true;
        for(int i = 0; i < p.size(); ++ i) {
            if(p[i] == \'*\') {
                dp[i + 1][0] = dp[i - 1][0];    // dp[i][0] = dp[i - 2][0]. 注意这一行的状态不要漏掉了.
            }
            for(int j = 0; j < s.size(); ++ j) {
                if(p[i] == s[j] || p[i] == \'.\') {
                    dp[i + 1][j + 1] = dp[i][j];        // dp[i][j] = dp[i - 1][j - 1];
                } else if(p[i] == \'*\') {
                    if(p[i - 1] == \'.\' || p[i - 1] == s[j]) {
                        dp[i + 1][j + 1] = (dp[i][j] | dp[i + 1][j]);    // dp[i][j] = dp[i - 1][j - 1] | dp[i][j - 1];     // 使用 1 个, 或继续使用 *
                    }
                    dp[i + 1][j + 1] = (dp[i + 1][j + 1]  | dp[i - 1][j + 1]);             // dp[i][j] = dp[i - 2][j];    // * 为 0 个
                }
            }
        }
        return dp.back().back();
    }
};

 

以上是关于leetcode 正则表达式匹配 困难的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——10.正则表达式匹配(困难)DP

leetcode困难10正则表达式匹配

leetcode困难10正则表达式匹配

leetcode困难10正则表达式匹配

⭐算法入门⭐《动态规划 - 串匹配》困难01 —— LeetCode 10. 正则表达式匹配

正则表达式匹配与自动机