心路历程:
这道题有点难,主要难在需要考虑的条件比较多,很难写出简洁的代码;此外,这道题的递推也有点复杂。看了网上的解答自己写了一个尽可能清晰的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)