LeetCode 10. 正則表達式匹配 44. 通配符匹配 (動態規劃)

給你一個字符串 s 和一個字符規律 p,請你來實現一個支持 ‘.’ 和 ‘*’ 的正則表達式匹配。

‘.’ 匹配任意單個字符 ‘*’ 匹配零個或多個前面的那一個元素 所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。

說明:

s 可能爲空,且只包含從 a-z 的小寫字母。 p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。 示例 1:

輸入: s = “aa” p = “a” 輸出: false 解釋: “a” 無法匹配 “aa” 整個字符串。 示例 2:

輸入: s = “aa” p = “a*” 輸出: true 解釋: 因爲 ‘*’ 代表可以匹配零個或多個前面的那一個元素,
在這裏前面的元素就是 ‘a’。因此,字符串 “aa” 可被視爲 ‘a’ 重複了一次。 示例 3:

輸入: s = “ab” p = “." 輸出: true 解釋: ".” 表示可匹配零個或多個(’*’)任意字符(’.’)。 示例
4:

輸入: s = “aab” p = “cab” 輸出: true 解釋: 因爲 ‘*’ 表示零個或多個,這裏 ‘c’ 爲 0 個,
‘a’ 被重複一次。因此可以匹配字符串 “aab”。 示例 5:

輸入: s = “mississippi” p = “misisp*.” 輸出: false

題解: 因爲存在*字符多匹配,因此考慮倒序匹配,並用數組記錄,從記錄的結果中遞推最優解,保證可行解中的TRUE能被傳遞下來.

首先考慮若不存在*時,只有 . 存在,那麼字符串長度一定要匹配,接着就是對應位置的字符是否相等或等於 . 了

當條件中給了*多匹配時,我們考慮對匹配串中的每一位找到模式串中對應的位置,在匹配過程中,fm即表示當前模式串與匹配串中的哪些位置能成功匹配,每一位匹配的是字符本身或 . 視爲該位置匹配成功,但是仍不能作爲連續匹配成功的依據.

之後將判斷匹配串中此時的之後一位是否是 *
若是 * 則判斷 當前字符i 以及之後的 * 再之後的串是否成功匹配, 若成功匹配則繼承下來,形成一段連續匹配成功的串.
當無法從當前這一輪延續成功的匹配結果時,就判斷能否使用上一輪的匹配結果進行延續,即dp[i+1][j]

當下一位不是 * 時,不能連續匹配多個重複字符, 表示必須以一一對應的方式匹配,直接從上一輪該位置之後的位置繼承匹配結果.

class Solution:
    def isMatch(self, text, pattern):
        dp=[[False]*(len(pattern)+1) for i in range(len(text)+1)]
        dp[-1][-1]= True
        for i in range(len(text),-1,-1):
            for j in range(len(pattern)-1,-1,-1):
                fm = i < len(text) and pattern[j] in (text[i],'.')
                if j+1 < len(pattern) and pattern[j+1]=='*':
                    dp[i][j]=dp[i][j+2] or fm and dp[i+1][j]
                else:
                    dp[i][j]=fm and dp[i+1][j+1]
        return dp[0][0]

給定一個字符串 (s) 和一個字符模式 § ,實現一個支持 ‘?’ 和 ‘*’ 的通配符匹配。

‘?’ 可以匹配任何單個字符。 ‘*’ 可以匹配任意字符串(包括空字符串)。 兩個字符串完全匹配纔算匹配成功。

說明:

s 可能爲空,且只包含從 a-z 的小寫字母。 p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 ? 和 *。 示例 1:

輸入: s = “aa” p = “a” 輸出: false 解釋: “a” 無法匹配 “aa” 整個字符串。 示例 2:

輸入: s = “aa” p = "" 輸出: true 解釋: '’ 可以匹配任意字符串。 示例 3:

輸入: s = “cb” p = “?a” 輸出: false 解釋: ‘?’ 可以匹配 ‘c’, 但第二個 ‘a’ 無法匹配 ‘b’。
示例 4:

輸入: s = “adceb” p = “ab” 輸出: true 解釋: 第一個 ‘’ 可以匹配空字符串, 第二個 '
可以匹配字符串 “dce”. 示例 5:

輸入: s = “acdcb” p = “a*c?b” 輸入: false

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        import ujson
        dp=[[False]*(len(p)+1) for i in range(len(s)+1)]
        dp[-1][-1]= True
        for i in range(len(s),-1,-1):
            for j in range(len(p),-1,-1):
                if i==len(s) and j==len(p):continue
                fm = i < len(s) and j< len(p) and p[j] in (s[i],'?','*')
                if j < len(p) and p[j]=='*':
                    dp[i][j]=dp[i][j+1] or fm and dp[i+1][j]
                else:
                    dp[i][j]=fm and dp[i+1][j+1]
        return dp[0][0]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章