1.题目解析

题目来源:10.正则表达式匹配——力扣

测试用例

2.算法原理

首先了解题目中的'*',该字符相当于模仿者,所以必须有一个本体供其模仿,并且该字符与本体合体后呈现出的是原来本体的n个连续字符,当n=0就呈现出空字符串

1.状态表示

此时需要将两字符串分不同区间进行判断,也就是使用布尔类型的二维dp表来存储两个字符串所对应的匹配关系,即

dp[i][j]: s字符串的 [0,i] 区间是否在p字符串的 [0,j] 区间完全匹配

2.状态转移方程

此时我们以p字符串的最后一个位置为突破口判断对应的三种情况并分类讨论,这里需要注意当最后一个位置为'*'时还要继续判断p[j-1]是'.'还是普通字符,再次分类讨论,具体思路如下:

3.初始化

这里为了填表方便开辟了虚拟位置,初始化时就需要对虚拟位置进行特殊处理,这里的虚拟位置就是当两个字符串为空串时的特殊情况

4.填表顺序

由状态转移方程可以知道填表时需要用到上面及左边的表内的值,所以需要从上向下填表,每一行需要从左到右填表

5.返回值

根据状态表示直接返回dp[m][n]即可

3.实战代码

代码解析

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size();
        int n = p.size();
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
        s = ' ' + s;
        p = ' ' + p;
        dp[0][0] = true;
        for (int j = 2; j <= n; j += 2) {
            if (p[j] == '*') {
                dp[0][j] = true;
            } else {
                break;
            }
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (p[j] == '*') {
                    dp[i][j] =
                        dp[i][j - 2] ||
                        (p[j - 1] == '.' || p[j - 1] == s[i]) && dp[i - 1][j];
                } else {
                    dp[i][j] =
                        (p[j] == '.' || p[j] == s[i]) && dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐