刷力扣学习记忆化递归[leetcode10. 正则表达式匹配]

刷力扣学习记忆化递归[leetcode10. 正则表达式匹配]

原题链接

https://leetcode-cn.com/problems/regular-expression-matching/

当你发现你的递归里有很多重复的函数调用的时候,就要想想使用记忆化递归了,使用起来就是在本来要return的时候先把他储存起来,然后再返回
同时,调用函数的时候多了几步,即,如果已经储存过,直接返回,如果没有储存过,则储存了再返回

题解

memo = [[None]*N for _ in range(M+1)] #用于储存
M,N = len(s),len(p)
def dfs (i,j):
    if j >= N:
        return i >= M
    
    if memo[i][j] != None:
        return memo[i][j]
    matchable = i < len(s) and p[j] in {s[i], '.'}
    if p[j+1] == '*' and j+1<N:
        if matchable:
            memo[i][j] = dfs(i+1,j) or dfs(i,j+2)
        else:
            memo[i][j] = dfs(i,j+2)
    else:
        memo[i][j] = matchable and dfs(i+1,j+1)
    return memo[i][j]

dfs(0,0)

这是一道困难题,我感觉主要的难点在于讨论应该结束的条件,题目中有两条字符串,做这种题时应该确定一条作为主字符串,谈论返回就只讨论它,这样思考起来就会简单很多。
除了使用记忆化递归,这题还可以使用DP来做,似乎其他人都是这么做的。。我也写一个DP的解法,其实递归与DP的思路非常相像,但DP还不用考虑这么多结束条件,暴力枚举就行了。

题解II

def isMatch(self, s: str, p: str) -> bool:
        M,N = len(s),len(p)
        def match (i,j):
            return i>=0 and bool(p[j] in {s[i],'.'})
        
        dp = [[False]*(N+1) for _ in range(M+1)] #多加一行一列来匹配空的情况
        dp[0][0] = True
        for i in range(M+1): #空与a*匹配的特殊情况
            for j in range(1,N+1):
                if p[j-1] ==  '*':
                    dp[i][j] |= dp[i][j-2] or (match(i-1,j-2) and dp[i-1][j])
                else:
                    dp[i][j] |= match(i-1,j-1) and dp[i-1][j-1]

        return dp[M][N]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值