https://leetcode.com/problems/regular-expression-matching/
思路
对以p中的每个元素为结尾的子序列,验证其与以s中每个元素为结尾的子序列是否匹配,此时复杂度为O(m*n).原问题转化为动态规划问题,转换函数为:
if p[i] == s[j] or p[i] == '.':
dp[i+1][j+1] = dp[i][j]
elif p[i] == '*' and (p[i-1] == s[j] or p[i-1] == '.'):
dp[i+1][j+1] = dp[i-1][j+1] or dp[i+1][j] or dp[i-1][j]
elif p[i] == '*' and p[i-1] != s[j]:
dp[i+1][j+1] = dp[i-1][j+1]
要考虑的细节
虽然思路有了,但是提交之后会有各种小问题,好在LeetCode会提示错误案例,方便调试
"aab"
"c*a*b"
对于这个例子,打印每个dp[i][j]发现dp[3][1]是False,这并不合理,其原因是dp[2][0]是False,于是对dp[i][0]重新赋值:
for i in range(p_len):
if p[i] == '*':
dp[i+1][0] = dp[i-1][0]
AC代码
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
s_len = len(s)
p_len = len(p)
dp = [[False for _ in range(s_len+1)] for _ in range(p_len+1)]
dp[0][0] = True
for i in range(p_len):
if p[i] == '*':
dp[i+1][0] = dp[i-1][0]
for i in range(p_len):
for j in range(s_len):
if p[i] == s[j] or p[i] == '.':
dp[i+1][j+1] = dp[i][j]
elif p[i] == '*' and (p[i-1] == s[j] or p[i-1] == '.'):
dp[i+1][j+1] = dp[i-1][j+1] or dp[i+1][j] or dp[i-1][j]
elif p[i] == '*' and p[i-1] != s[j]:
dp[i+1][j+1] = dp[i-1][j+1]
return dp[p_len][s_len]