其他分享
首页 > 其他分享> > leetcode 剑指offer 19. 正则表达式匹配

leetcode 剑指offer 19. 正则表达式匹配

作者:互联网

leetcode 剑指offer 19. 正则表达式匹配

解体思路:动态规划

我们每次从字符串 p 中取出 一个字符 或者「字符 + 星号」的组合,并在 s 中进行匹配。我们用f[i][j]表示s的前i个字符和p的前j个字符是否能够匹配。在进行状态转移时,我们先考虑p的第j个字符的匹配情况。
可分为以下几种情况:

1. 当p中的第j个字符是一个小写字母,则必须在s中匹配一个相同的小写字母,即
在这里插入图片描述
如果s的第i个字符与p的第j个字符不同,则匹配失败;如果相同,则最后完整的匹配结果取决于这两个字符前面的部分是否能够匹配,因此对比是的i-1个字符与p的j-1个字符。

2. 当p中第j个字符是 . ,它能匹配任意字符 ,因此可以得出
f[i][j]=f[i-1][j-1]

3. 当p中的第j个字符是 * ,就表示可以对p中的第j-1个字符匹配任意次(0次或者多次)。在这种情况下,把第j-1个字符(假设是c)和第j个字符看成一个组合,为 c *。
情况一:匹配 s 末尾的一个字符,将该字符扔掉,而该组合还可以继续进行匹配。
情况二:不匹配字符,将该组合扔掉,不再进行匹配在这里插入图片描述

  1. 当s[i]=p[j-1]时,c * 可分为看和不看2种情况,
    第一种,看:正则串p不动,主串s前移一个:f[i][j]=f[i-1][j]
    第二种,不看,即忽略c*,直接砍掉:f[i][j]=f[i][j-2]
    例如:s:abb, p:abbb*
  2. 当s[i] != p[j-1]时,直接砍掉c : f[i][j]=f[i][j-2]
    例如: s: abb,p: abbc

因此,最终的状态转移方程如下所示:
在这里插入图片描述
其中 matches(x,y) 判断两个字符是否匹配的辅助函数。只有当 y 是 . 或者 x 和 y 本身相同时,这两个字符才会匹配。

初始化:
动态规划的边界条件为 f[0][0]=true,即两个空字符串是可以匹配的。最终的答案即为 f[m][n],其中 m 和 n 分别是字符串 s 和 p 的长度。
特判:需要考虑空串空正则

  1. 空串和空正则是匹配的,f[0][0]=true
  2. 空串和非空正则,不能直接定义 true 和 false,必须要计算出来。(比如 A= ‘’ ‘’ , B=a∗b∗c∗)
  3. 非空串和空正则必不匹配,f[1][0]=…=f[n][0]=false
  4. 非空串和非空正则,那肯定是需要计算的了。
    在这里插入图片描述
    复杂度分析
    时间复杂度:O(mn),其中 m 和 n 分别是字符串 s 和 p 的长度。我们需要计算出所有的状态,并且每个状态在进行转移时的时间复杂度为 O(1)。
    空间复杂度:O(mn),即为存储所有状态使用的空间。

标签:字符,匹配,offer,19,复杂度,正则,空串,leetcode,个字符
来源: https://blog.csdn.net/weixin_42290685/article/details/120457101