Leetcode 10. 正则表达式匹配

在这里插入图片描述

心路历程:

这道题有点难,主要难在需要考虑的条件比较多,很难写出简洁的代码;此外,这道题的递推也有点复杂。看了网上的解答自己写了一个尽可能清晰的AC解。

这道题是动态规划题:
状态:当前两个子串是否完全匹配
动作候选集:s后移0或1位,p后移0或1或2位
返回值:当前子串是否匹配

注意的点:

1、这道题的递推关系是从前往后找的,一般的双字符串问题都是从后向前找
2、这道题的条件判断很多,但是很多条件是可以合并的

解法:字符串动态规划

class Solution:
    def isMatch(self, s, p):

        @cache
        def dp(part_s, part_p):
            if part_p == '':  return part_s == ''
            # if part_s == '':  # 不能写这个条件,因为p可能用*把p变空

            first_match = bool(part_s) and part_p[0] in [part_s[0], '.']  # 看两个字符串的首位是否匹配

            if len(part_p) >= 2 and part_p[1] == '*':  # 主要针对模式串的状态进行分类讨论
                if first_match:
                    return dp(part_s[1:], part_p) or dp(part_s, part_p[2:])  # 1. 可以无限后移直到第一个不再匹配,发挥*的作用 2.把p第一个元素消去  
                else:
                    return dp(part_s, part_p[2:])  # 只能把p的第一个元素消去,p后移两位
            else:
                if first_match:
                    return dp(part_s[1:], part_p[1:])  # 共同后移一位
                else:
                    return False

        return dp(s, p)
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值