动态规划:剑指 Offer 19. 正则表达式匹配

题目描述:

请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。

在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。

 

 

 

 

解题思路:

 

 

 

因此,本题的状态共有 m×n 种,应定义状态矩阵 dp ,dp[i][j] 代表 s[:i] 与 p[:j] 是否可以匹配。

做好状态定义,接下来就是根据 「普通字符」 , 「.」 , 「*」三种字符的功能定义,分析出动态规划的转移方程。

动态规划解析:

 

 

复杂度分析:
时间复杂度 O(MN) : 其中 M,N 分别为 s 和 p 的长度,状态转移需遍历整个 dp 矩阵。
空间复杂度 O(MN) : 状态矩阵 dp 使用 O(MN) 的额外空间

复制代码
class Solution{
    public boolean isMatch(String s,String p){
        int m = s.length()+1,n = p.length()+1;
        boolean dp[][] = new boolean[m][n];
        dp[0][0] = true;
        // 初始化首行
        for(int j=2;j<n;j+=2){
            dp[0][j] = dp[0][j-2]&&p.charAt(j-1)=='*';
        }
        // 状态转移
        for(int i=1;i<m;i++) {
            for (int j = 1; j < n; j++) {
                if (p.charAt(j - 1) == '*') {
                    if(dp[i][j-2]) dp[i][j] = true;//1.
                    else if(dp[i-1][j]&&s.charAt(i-1)==p.charAt(j-2)) dp[i][j] = true;//2.
                    else if(dp[i-1][j]&&p.charAt(j-2)=='.') dp[i][j] = true;//3.
                }else{
                    if(dp[i-1][j-1]&&s.charAt(i-1)==p.charAt(j-1)) dp[i][j]=true;//1.
                    else if(dp[i-1][j-1]&&p.charAt(j-1)=='.') dp[i][j] = true;//2.
                }
            }
        }
        return dp[m-1][n-1];
    }
}
复制代码

 

dp五部曲:
        1.状态定义(确定dp数组及其下标含义)
        2.状态转移(确定递推公式)
        3.初始化(dp数组初始化):初始化dp[1]=1即可
        4.遍历顺序
        5.返回坐标:返回dp[n]
posted @   ZDREAMER  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示