面试题19. 正则表达式匹配
1.s[i-1]==p[j-1]
dp[i][j] = dp[i-1][j-1];
dp[i][j] = dp[i-1][j-1];
2.s[i-1]!=p[j-1]
1)p[j-1]=='.'
'.'是万能字符,可以直接让'.'等于s[i]处的字符
dp[i][j] = dp[i-1][j-1];
2)p[j-1]=='*'
'*'可以匹配零个或多个前面的元素,而是否能取多个或1个字符要看j-2的字符是否和i-1的字符相同。因此首先要判断p[j-2]==s[i-1]
(1)p[j-2]!=s[i-1]
j-2的字符不等于i-1的字符,那就只能让*代表取0个字符。
dp[i][j] = dp[i][j-2] (相当于去掉p[j-1]和p[j-2])
(2)p[j-2]==s[i-1]||p[j-2]=='.'
可以让*代表0个字符或多个字符,如果p[j-2]为'.'就可以替换为s[i-1]的字符
'*'取0个字符
例子:s:aab,p:aabb*,虽然j-2和i-1相等,但是dp[i][j-2]已经匹配了,直接删去j-1和j-2即可(你来之前我们就已经是总冠军了)
dp[i][j] = dp[i][j-2] (取0个字符)
1)p[j-1]=='.'
'.'是万能字符,可以直接让'.'等于s[i]处的字符
dp[i][j] = dp[i-1][j-1];
2)p[j-1]=='*'
'*'可以匹配零个或多个前面的元素,而是否能取多个或1个字符要看j-2的字符是否和i-1的字符相同。因此首先要判断p[j-2]==s[i-1]
(1)p[j-2]!=s[i-1]
j-2的字符不等于i-1的字符,那就只能让*代表取0个字符。
dp[i][j] = dp[i][j-2] (相当于去掉p[j-1]和p[j-2])
(2)p[j-2]==s[i-1]||p[j-2]=='.'
可以让*代表0个字符或多个字符,如果p[j-2]为'.'就可以替换为s[i-1]的字符
'*'取0个字符
例子:s:aab,p:aabb*,虽然j-2和i-1相等,但是dp[i][j-2]已经匹配了,直接删去j-1和j-2即可(你来之前我们就已经是总冠军了)
dp[i][j] = dp[i][j-2] (取0个字符)
'*'取1个字符
例子:s:aab,p:aab*
dp[i][j] = dp[i][j-1] (取1个字符,相当于去掉p[j-1])
例子:s:aab,p:aab*
dp[i][j] = dp[i][j-1] (取1个字符,相当于去掉p[j-1])
'*'取多个字符
例子:s:aabb,p:aab*,要判断的是s:aab和aab* 是否可以匹配,如果可以匹配的话,那么s后面再加上一个b也没关系,因为*可以变成多个b。
dp[i][j] = dp[i-1][j] (取多个字符)
例子:s:aabb,p:aab*,要判断的是s:aab和aab* 是否可以匹配,如果可以匹配的话,那么s后面再加上一个b也没关系,因为*可以变成多个b。
dp[i][j] = dp[i-1][j] (取多个字符)
3)else(j处就是个普通字符,dp[i][j]肯定不能匹配了,其实这里写不写都可以,只不过为了让大家看着思路清晰。)
dp[i][j] = false;
dp[i][j] = false;
class Solution: def isMatch(self, s: str, p: str) -> bool: dp = [[False]*(len(p)+1) for _ in range(len(s)+1)] dp[0][0] = True for j in range(2, len(p)+1): if p[j-1] == '*': dp[0][j] = dp[0][j-2] for i in range(1, len(s)+1): for j in range(1, len(p)+1): if s[i-1] == p[j-1]: dp[i][j] = dp[i-1][j-1] elif p[j-1] == ".": dp[i][j] = dp[i-1][j-1] elif p[j-1] == "*": if p[j-2] == '.' or s[i-1] == p[j-2]: dp[i][j] = dp[i-1][j] or dp[i][j-1] or dp[i][j-2] else: dp[i][j] = dp[i][j-2] return dp[-1][-1]