Regular Expression Matching解题心得
来源:互联网 发布:牛顿环实验数据参考 编辑:程序博客网 时间:2024/06/09 21:03
Regular Expression Matching解题心得
My code:https://github.com/zhanzongyuan/leetcode/blob/master/010_Regular%20Expression%20Matching.cpp
Problem source: https://leetcode.com/problems/regular-expression-matching/description/
- Regular Expression Matching解题心得
- 题目重述
- 解题思路
题目重述
输入两个字符串,一个是普通字符串s,一个是简化的正则表达式r,r除了26个小写字母外还包含’.’和’*’。r里的正则表达式’x*’代表匹配多个连续的x或则0个字符,’.’则是匹配所有的字母
解题思路
最初思路:使用stack的思路,从后往前逐个进行匹配,但是对于’*’和’.’的特例情况无法彻底解决,只能通过“加插件”的方式对其补充特殊情况,这种方法导致自己越补漏洞越出现新的bug。所以需要取得新的思考方向,得到一个可证明的方法。
- 总结,以后当一个思路修修补补了很多后就不要用这个思路了,换一个试试,因为这样的方法不优雅
递归思路:isMatch(ssss, x*xxx)=isMatch(ssss, xxx) | | ((s==x||x==’.’)&&isMatch(sss, x*xxx));以及isMatch(ssss, xxxx)=isMatch(sss, xxx);得到状态递归方程,通过该方程递推判断;其实可以看作一个深度搜索,对所有情况递归遍历。时间复杂度,可以对最坏情况进行分析,即正则式是这种形式’x*x*x*’,则每次递归都会进入两个子程序,考虑近似于遍历满二叉树,则树的最大深度为T+P/2,则时间复杂度O(
2T+P/2 );达到指数级- 代码部分实现如下:
//v 1.0 Recursionclass Solution {public: bool isMatch(string s, string p) { if (p.size()==0) { return s.size()==0; } bool first_match=s.size()!=0&&(s[0]==p[0]||p[0]=='.'); if (p.size()>=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)); } }};
- 代码部分实现如下:
动态规划思路:
- Top-Down : 类似于上面的递归思路,但是,递归的思路做了很多重复运算,所以可以用一个矩阵保存已经计算过的结果,传入每一层的递归调用中,减少不必要的重复计算。这里通过递归调用的方法实现
- Bottom-Up:不需要进行函数自身的递归调用,通过状态转移方程可以知道,一个状态的答案由右边的状态和下一层的状态决定,应该对整个状态矩阵进行从底向上从右到左的计算,最底层的计算可以在上面几层的计算里使用到
Bottom-Up注意点:注意点:对于边界值的特殊情况的处理需要仔细斟酌,矩阵的两个维度可以大多一排,存特殊值。
- 部分Bottom-Up代码实线,这里是改进版的bottom-up,是从前向后进行计算,但是思想是一样的
//v 2.0 DP 动态规划class Solution {public: bool isMatch(string s, string p) { /** * dp[i+1,j+1]: s[0:i] matchs p[0:j] * dp[i+1,j+1]== (p[j]!='*'&&((p[j]=='.'||p[j]==s[i])&&dp[i,j])) * && (p[j]=='*' &&( * dp[i+1, j-1] //x* repeat 0 times * || ((p[j-1]=='.'||p[j-1]==s[i])&&dp[i, j+1])) //x* repeat >=1 times * * !!!对i=0 or j=0 的dp[i][j]特殊处理 * i==0 && j==0: true * i==0 && j+1<>0: dp[0][j+1]=p[j]=='*'&&dp[0][j-1] */ int n=s.length(), m=p.length(); vector<vector<bool>> dp(n+1, vector<bool>(m+1, false)); dp[0][0]=true; for(int j=1; j<m; j++){ dp[0][j+1]=p[j]=='*'&&dp[0][j-1]; } for(int i=1; i<n; i++){ dp[i][0]=false; } for (int i=0; i<n; i++){ for (int j=0; j<m; j++){ if (p[j]!='*'){ dp[i+1][j+1]=(p[j]=='.'||p[j]==s[i])&&dp[i][j]; } else{ dp[i+1][j+1]=dp[i+1][j-1]||((p[j-1]=='.'||p[j-1]==s[i])&&dp[i][j+1]); } } } return dp[n][m]; }};
- 部分Bottom-Up代码实线,这里是改进版的bottom-up,是从前向后进行计算,但是思想是一样的
- dp的时间复杂度显而易见即矩阵遍历的时间复杂度O(TP),相对于递归的指数级时间复杂度优化很多
- Regular Expression Matching解题心得
- [leetcode] 10. Regular Expression Matching 解题报告
- leetcode解题笔记:Regular Expression Matching
- [Leetcode] 10. Regular Expression Matching 解题报告
- [LeetCode] Regular Expression Matching 解题报告
- [LeetCode 解题报告]010.Regular Expression Matching
- Leetcode #10 Regular Expression Matching 正则表达式匹配 解题小节
- (待解决)LeetCode 10. Regular Expression Matching 解题报告
- 【LeetCode】10.Regular Expression Matching(hard)解题报告
- LeetCode: Regular Expression Matching
- LeetCode: Regular Expression Matching
- leetcode Regular Expression Matching
- [Leetcode] Regular Expression Matching
- Regular Expression Matching
- Regular Expression Matching
- [LeetCode]Regular Expression Matching
- Regular Expression Matching
- LeetCode-Regular Expression Matching
- 最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
- 自己写的简单的折叠板例子
- 免费的号码归属地查询API
- 浅谈Java中的equals和==
- HTML DOM中DIV的Style:margin,border,padding
- Regular Expression Matching解题心得
- Linux下spi驱动开发
- 自媒体平台支持原创,自媒体人不会原创怎么写文章
- 继承HttpServletRequestWrapper 实现request中流的重复获取
- 深度学习图片卷积输出大小计算公式
- 自定义插值器合集
- LeetCode:M-279. Perfect Squares
- 浅谈Java中static的作用
- Android Sharedpreferences清空的正确方法