10. Regular Expression Matching
problem description
Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
.
The matching should cover the entire input string (not partial).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
.
Example 1:
Example 2:
Example 3:
Example 4:
Example 5:
algorithm thought
正则表达式问题,两个字符串匹配。碰到字符串问题,一般都是动态规划问题,或者是字符串匹配的一些专门的算法,比如kmp这种。还有就是很多字符串,如果想要找到前缀重合之类的问题,就是trie字典树。正则表达式问题就是典型的动态规划解决的题目。使用一个二维数组保存每一个状态,横纵坐标ij表示s[0-i]和p[0-j]的匹配结果。每一个状态转移的时候,一定要分析全要考虑的前一个状态。这一题中就*号很特殊,他可以是一个也可以是零个也可以是多个。分析到*号的时候,需要考虑的前一个状态有点多。
分析一次example4的二维数组是如何构造的
首先考虑一般情况,如果两个字符相等了,只需要查看左上角的bool值即可,如果匹配当前也是匹配的。如果是一个点,那也好说,直接按照相等来匹配。关键就是如何匹配*。我们来回顾一下*的定义,首先可以是0个,0个的话,直接查看靠左两个方格的bool值即可,比如c*和空字符比较,也就是第一排前三个。两个空字符肯定是匹配的,值为1,c和空字符肯定不匹配,格子值为0,c*是和空字符匹配的,因为可以是0个c,所以,直接观察左边两个格子的值即可。然后考虑1个的情况,现在可以换一种思想,如果当前行列匹配需要1个字符,那么上一行和当前列匹配肯定是只需要0个字符,如果上一行成功匹配,那么这一行肯定也成功。同理可得1个或者多个匹配的话,只需要看上一个格子是否满足条件即可。
可能讲述的还是不清晰,建议先做简单的动态规划解法字符串匹配问题。比如最长公共子序列等问题,再来做这题会清晰很多。
code
algorithm analysis
定义了一个二维数组,如果s的长度为m,p的长度为n。二维数组就是一个m*n的矩形。算法需要遍历这个二维数组,循环中时间复杂度为O(1),最后时间复杂度是O(mn)
Last updated