剑指 Offer 19. 正则表达式匹配

题目:剑指 Offer 19. 正则表达式匹配

image

优质解答:动态规划(参考自AccSrd)
  • 首先s,p两串均空可以匹配;
  • s,p有一串为空:
    • p为空,s非空则不可匹配;
    • s为空,p非空,则可能匹配,如\(a*b*.*\)这类,所以需要单独判断一下当p[j-2]=='*',dp[i][j]取决于dp[i-2][j]
  • 当s,p两串均非空时:
    • 当p[j-1]为'*'时,我们需要判断s[i-1]和p[j-2]是否相同或者p[j-2]是否为'.',如果直接相同或者p[j-2]为'.',则dp[i][j]取决于dp[i-2][j]或者dp[i][j-1];如果s[i-1]和p[j-2]不同,且p[j-2]还不是'.',dp[i][j] = dp[i-2][j]
    • 当p[j-1]不为'*'时,直接判断s[i-1]和p[j-1]是否相同或p[j-2]是否为'.',如果相同或p[j-2]为'.',则dp[i][j] = dp[i-1][j-1];如果s[i-1]和p[j-2]不同,且p[j-2]还不是'.',dp[i][j] = false
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        def match(s, p):
            return s == p or p == '.'

        dp = [[False] * (len(s) + 1) for _ in range(len(p) + 1)]
        dp[0][0] = True
        for i in range(1, len(p) + 1):
            if p[i - 1] == '*':
                dp[i][0] = dp[i - 2][0]

        for i in range(1, len(p) + 1):
            for j in range(1, len(s) + 1):
                if p[i - 1] == '*':
                    if match(s[j - 1], p[i - 2]):
                        dp[i][j] = dp[i - 2][j] or dp[i][j - 1]
                    else:
                        dp[i][j] = dp[i - 2][j]
                else:
                    dp[i][j] = match(s[j - 1], p[i - 1]) and dp[i - 1][j - 1]
        return dp[-1][-1]
遇到问题及解决方法:
  • 最初生成数组的时候误使用了dp=[[[False] * (len(s) + 1)]] * (len(p) + 1),应使用dp = [[False] * (len(s) + 1) for _ in range(len(p) + 1)]
    • *这个操作,一旦改变原列表某一个值,复制的列表也会随之改变。如a = [[False] * 2] * 2最终生成[[False, False],[False, False]],一旦更改a[0][0],则a[1][0]也会随之改变
posted @ 2022-04-08 13:35  面包房主人  阅读(38)  评论(0)    收藏  举报