【LeetCode】面试题19. 正则表达式匹配
题目:
思路:
1、动态规划:从尾部开始(不从头部),清晰分析每种情况,划分子问题,得到转移方程,初始条件特殊单独分析处理
- 定义状态
dp[i][j]
表示s的前i个字符和p的前j个字符是否匹配,注意前i个字符的下标是0~i-1
- 重叠子问题,怎么确定
dp[i][j]
的状态?通过对比当前尾部的字符,将dp[i][j]
的问题划分成子问题s[i-1] == p[j-1]
或p[j-1] == ‘.‘
:当前尾部两个字符完全匹配,则dp[i][j] = dp[i-1][j-1]
p[j-1]==‘*‘
:需要根据前一个字符确认s[i-1] == p[j-2]
或p[j-2] == ‘.‘
:则可以匹配0个或多个字符,匹配0个时dp[i][j] = dp[i][j-2]
,匹配多个时dp[i][j] = dp[i-1][j]
s[i-1] != p[j-2]
:*
匹配0个字符,则dp[i][j] = dp[i][j-2]
- 其它情况
dp[i][j]=False
- 转移方程
\(DP_{i,j} = \begin{cases} DP_{i-1,j-1} & s_{i-1}=p_{j-1}\ ||\ \ p_{j-1}=. \DP_{i-1,j}\ ||\ DP_{i,j-2} & p_{j-1}=*\ , s_{i-1}=p_{j-2}\ ||\ \ p_{j-2}=. \\ DP_{i,j-2} & p_{j-1}=*\ , s_{i-1} \ne p_{j-2} \False & others\end{cases}\) - 初始条件
- 当两个字符串都为空时
dp[0][0]=False
- 当s不为空,p为空时
dp[i][0]=False
- 当s为空,p不为空时
dp[0][j]
的状态需要判断
- 当两个字符串都为空时
- 推导转移公式时是从后向前,得到公式之后计算时需要从前往后。因为后面的计算依赖前面已计算出来的结果
2、既然能够分解成子问题就能够通过递归回溯求解,并且是从后向前进行,注意递归的结束条件
代码:
Python
class Solution(object): def isMatch(self, s, p): """ :type s: str :type p: str :rtype: bool """ m = len(s) n = len(p) # 0表示空字符串, 1表示第一个字符, 第一个字符在字符串里下标是0 dp = [[False for _ in range(n+1)] for _ in range(m+1)] dp[0][0] = True # 都是空字符串 for i in range(1, n+1): if p[i-1] == ‘*‘ and dp[0][i-2]: dp[0][i] = True # 注意i,j在dp中和在s/p中的变化,容易乱 for i in range(1, m+1): for j in range(1, n+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 s[i-1] == p[j-2] or p[j-2] == ‘.‘: dp[i][j] = dp[i-1][j] or dp[i][j-2] else: dp[i][j] = dp[i][j-2] else: dp[i][j] = False return dp[m][n]
class Solution(object): def isMatch(self, s, p): """ :type s: str :type p: str :rtype: bool """ # 两个都为空 if len(s) == 0 and len(p) == 0: return True # s不为空, p为空 if len(p) == 0: return False # s为空, p不为空, 只要p的长度为偶数并且奇数位为*就能匹配 if len(s) == 0: if len(p) % 2 != 0: return False else: for i in range(1, len(p), 2): if p[i] != ‘*‘: return False return True # 两个都不为空, 进入递归 if s[-1] == p[-1] or p[-1] == ‘.‘: return self.isMatch(s[:-1], p[:-1]) elif p[-1] == ‘*‘: if s[-1] == p[-2] or p[-2] == ‘.‘: return self.isMatch(s[:-1], p) or self.isMatch(s, p[:-2]) else: return self.isMatch(s, p[:-2]) else: return False
相关问题
相关推荐
码墨 2020-06-16
wangzhaotongalex 2020-10-20
rechanel 2020-11-16
cshanzhizi 2020-10-16
luofuIT成长记录 2020-09-22
taomengxing 2020-09-07
MaggieRose 2020-08-19
jyj00 2020-08-15
MaggieRose 2020-07-04
modaiairen 2020-06-28
ziggurat 2020-06-28
JnX 2020-06-27
jyj00 2020-06-26
山水沐光 2020-06-25
shqhope 2020-06-23
eroshn 2020-06-21
wyq 2020-11-11
TLROJE 2020-10-26
风雨断肠人 2020-10-13