-
「手画图解」动态规划,需要仔细的分情况讨论这个解析让我发现我之前对*的理解有误。**的作用是使前一个字符出现0次,1次或以上次。
-
视频图解 动态规划 正则表达式这个讲的特别透彻,一步步填表,十分清晰!
-
官方的解析没看懂
动态规划视频解析:
- 初始状态为表格的第一行和第一列。
- 转移方程如下:
具体代码:
class Solution:
def isMatch(self, s: str, p: str) -> bool:
slen, plen = len(s), len(p)
dp = [ [False] * (plen + 1) for _ in range(slen + 1)] # 创建slen+1 * plen+1 的二维数组
dp[0][0] = True # 两空串匹配成功
for col in range(1, plen + 1): #初始化第一行
dp[0][col] = dp[0][col - 2] if p[col - 1] == '*' else False # p的下标从0开始,dp[0]对应的为空,可以说是从1开始遍历p,s的。
# 当前字符为*,此时*的作用是使得前一个字符出现0次(与空串匹配呢),这种情况下,如果前两列与空串匹配成功,则当前两字符串匹配成功
# 不用担心-2会越界,因为题目保证了每次出现字符 * 时,前面都匹配到有效的字符
for row in range(1, slen + 1):
for col in range(1, plen + 1):
# s[row - 1]是因为数组下标从0开始
if s[row - 1] == p[col - 1] or p[col - 1] == '.': # 字符相匹配,或者.匹配任意字符
dp[row][col] = dp[row - 1][col - 1]
elif p[col - 1] == '*':
if dp[row][col - 2] == True: # *的作用:前一个字符出现0次
dp[row][col] = True
elif s[row - 1] == p[col - 2] or p[col - 2] == '.': # *的作用:前一个字符出现1次或以上次,直接复制上一行的匹配结果
# !注意:.匹配任意字符,不要漏掉
dp[row][col] = dp[row - 1][col]
return dp[slen][plen]
还可以参考这个解析 动态规划 - 从 0 讲解,大白话好理解 不过我觉得视频解释的也非常好!