动态规划:剑指 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]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)