动态规划:保存之前的计算结果以避免重复计算
- 自下而上:先解决子问题,逐步填表(Tabulation)
- 自上而下:不断分解问题直到最小,记忆存储(Memorization)
题目要求
给定字符串 s 和字符规律 p,判断s能否由p匹配。
p[0 : j] 能否匹配 s[0 : i] 与其子问题(如 p[0 : j - 1] 能否匹配 s[0 : i])的解有关,考虑用自下而上填表方式。
令dp[i][j] 表示 s[0 : i] 能否由匹配 p[0 : j] ,这里由于*的存在可以有空字符,所以令dp[i + 1][j + 1] 表示 s[0 : i] 能否由匹配 p[0 : j] ,用dp[0][:] 表示s前空字符的匹配,然后分析与子问题的解的关系…
class Solution:
def isMatch(self, s: str, p: str) -> bool:
if s is None or p is None:
return False
# 初始化全为否
dp = [[False] * (len(p) + 1) for _ in range(len(s) + 1)]
# 空字符可以匹配
dp[0][0] = True
# 初始化空字符是否可匹配
for i in range(2, len(p) + 1):
if p[i - 1] == '*':
dp[0][i] = dp[0][i - 2]
# 逐步填表解决子问题,最后得到解
for i in range(1, len(s) + 1):
for j in range(1, len(p) + 1):
if s[i - 1] == p[j - 1] or p[j - 1] == '.':
dp[i][j] = dp[i - 1][j - 1]
elif p[j - 1] == '*':
if p[j - 2] != s[i - 1] and p[j - 2] != '.':
dp[i][j] = dp[i][j - 2]
else:
dp[i][j] = dp[i - 1][j] or dp[i][j - 1] or dp[i][j - 2]
return dp[len(s)][len(p)]
本文介绍如何使用动态规划解决正则表达式的匹配问题,通过自下而上的方式逐步填表,避免重复计算。文章详细解释了dp[i][j]的含义,并给出具体的实现代码,展示了如何处理字符'*'的特殊情况。
2187

被折叠的 条评论
为什么被折叠?



