10、正则表达式
基本思想:
动态规划
具体实现:
1.确认状态:
最后一步----dp[i][j],代表s[0:i]和p[0:j]是否匹配
dp里面的i和j是s和p的长度
子问题---dp[i-1][j-1],dp[i][j-2],dp[i-1][j-2],dp[i-1][j]
2、状态转移公式:
3、初始状态:
- p为空串,s不为空串,肯定不匹配。
- s为空串,但p不为空串,要想匹配,只可能是右端是星号,它干掉一个字符后,把 p 变为空串。
-
for j in range(1, p_len + 1): if p[j - 1] == '*': dp[0][j] = dp[0][j - 2]
- s、p都为空串,肯定匹配。 dp[0][0] = True
4、计算顺序:
从左到右 如果中间遇到False也不会退出,说不定往后走两步就碰到*,就变成Ture了,如果当下是False也会继续往后走
代码:
class Solution: def isMatch(self, s: str, p: str) -> bool: s_len = len(s) p_len = len(p) # dp[i][j] 表示 s[:i] 与 p[:j] 是否匹配,各自前 i、j 个是否匹配 dp = [[False] * (p_len + 1) for _ in range(s_len + 1)] dp[0][0] = True # s 为空串 for j in range(1, p_len + 1): # 若 p 的第 j 个字符 p[j - 1] 是 '*' # 说明第 j - 1、j 位可有可无 # 那么如果前 j - 2 个已经匹配上,前 j 个也可以匹配上 if p[j - 1] == '*': dp[0][j] = dp[0][j - 2] for i in range(1, s_len + 1): for j in range(1, p_len + 1): if p[j - 1] in {s[i - 1], '.'}: # A dp[i][j] = dp[i - 1][j - 1] elif p[j - 1] == '*': # B if p[j - 2] in {s[i - 1], '.'}: # (1) dp[i][j] = dp[i][j - 2] or dp[i - 1][j - 2] or dp[i - 1][j] else: # (2) dp[i][j] = dp[i][j - 2] return dp[s_len][p_len]