1. 程式人生 > 遊戲資訊 >群星程式碼(最全修正合集,可極大增強遊戲性)

群星程式碼(最全修正合集,可極大增強遊戲性)

題目:劍指 Offer 19. 正則表示式匹配
優質解答:動態規劃(參考自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]也會隨之改變