leetcode题库python3解题:10.正则表达式匹配

思路:字符串 s, 字符规律p

  1. 匹配s第一个字符是否是 ‘.’ 或者相等
  2. 判断下一个是否是’ * ‘,是则优先匹配’ * '后一个,否则p无法前进,无法匹配再回来匹配当前第一个, 成功匹配则p前进到下一个
  3. 第一个匹配成功,且第二个不是星号,则p和s同时前进
  4. 递归每次匹配一到两个字符

代码实现

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
      		# 当p走到最后,s走完为True ,没走完为False
            if not p: return not s 
            # 判断当前第一个字符
            same = True if s and p[0] in {'.', s[0]} else False
            # 有星号匹配第三位,不匹配p无法前进
            # 匹配第一位
            # 无星号,匹配同步前进
            return len(p) >= 2 and p[1] == '*' and  (self. isMatch(s,p[2:]) or same and self.isMatch(s[1:],p)) or same and self.isMatch(s[1:],p[1:])
      

动态规划

动态规划有一个比较混淆的点就是下标/索引
以 s= “aab” p="cab"为例
初始图
在这里插入图片描述

1. 用一个二维数组来表示动态表,由图可以看出
  • dp[ i ][ j ]表示的是s[i-1] 与p[j-1]的匹配情况
  • 第一个中括号代表第 i 行 对应s的下标 i-1,第二个中括号代表 j 列对应p的下标 j-1
  • 按图中当匹配成功就改 False 为 True,当遍历结束,将True顺利传递到最后,即匹配成功
  • 往后的匹配依赖前面的匹配结果
2. 初始化dp表预留第一行第一列来保存
  • 初始化星号✳️所在列第0行为标记为True
  • dp[0][0] 预设为True相当于在匹配之前虚构一个成功匹配
3. 条件判断

a. 没有遍历到星号✳️:
比较当前 s[i-1] == p[j-1] or p[j-1] == ‘.’ 考虑到匹配成功p和s 各进一位,把左上的True传递给当前位置dp[i][j] = dp[i - 1][j - 1]
b. 遍历到星号✳️ p[j-1] == ‘*’ 分两种情况:

  • 星号是0到多次,比较前缀找到匹配 :s[i-1] == p[j - 2] or p[j- 2] == ‘.’
    匹配时,匹配时 dp[i][j] = dp[i][j - 2] or dp[i - 1][j] , 分两种情况:
    (1) 第一个星号匹配成功接受第0行的星号 dp[i][j] = dp[ i-1 ][ j ]
    (2) 后续星号传递前缀之前的匹配值即 dp[ i ][ j ] = dp[ j ][ j-2 ]
  • 不匹配,跳过前缀+星号 dp[i][j] = dp[i][j - 2]
1. 匹配过程匹配成功的True的传递(p=“cab, s=“aab”)

在这里插入图片描述

2.匹配过程匹配成功的True的传递(p=“acb, s=“aab”)

在这里插入图片描述

class Solution:
	def isMatch( s: str, p: str) -> bool:
	    ls, lp = len(s), len(p)
	    # 初始化动态表
	    dp = [[False for _ in range(lp + 1)] for _ in range(ls + 1)]
	    dp[0][0] = True
	    # 动态检查的前置条件
	    for j in range(2, lp + 1):
	        dp[0][j] = dp[0][j - 2] and p[j - 1] == '*'
	    # 遍历动态表
	    for i in range(1, ls + 1):
	        for j in range(1, lp + 1):
	            if p[j-1] == '*':
	            	# 星号前的符号与当前字符匹配
	                if s[i-1] == p[j - 2] or p[j- 2] == '.':
	                    dp[i][j] = dp[i][j - 2] or dp[i - 1][j]
	                else:
	                    dp[i][j] = dp[i][j - 2]
	            elif s[i-1] == p[j-1] or p[j-1] == '.':
	                dp[i][j] = dp[i - 1][j - 1]
	    return dp[-1][-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值