LeetCode 10 : 正則表達式匹配

題目描述

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s could be empty and contains only lowercase letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like . or *.


給定一個字符串 (s) 和一個字符模式 (p)。實現支持 '.' 和 '*' 的正則表達式匹配。
'.' 匹配任意單個字符。
'*' 匹配零個或多個前面的元素。
匹配應該覆蓋整個字符串 (s) ,而不是部分字符串。
說明:
s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。

解題思路

根據題意,給定兩個假設:

  1. * 不能出現在開頭
  2. 不能出現連續的*(兩個或多個)

基于動態規劃的解題思路:

matrix[i][j]表示s的前i個字符[0,i)組成的subString,與p的前j個字符[0,j)組成的subString的匹配結果,可以推斷,matrix[i][j]可以由已知的狀態推斷出未知的狀態

遞推矩陣的初始化

矩陣的大小應該是matrix[len(s)][len(p)]

  1. matrix[0][0]表示s和都是null,可以匹配,返回True
  2. s為非null,p是null,永遠不匹配,返回False
  3. s為null,p為非null時,需要分情況:如果沒有*,則一定不能匹配;
    (注意:根據題意描述,我們推斷: *不能是第一個字符,同時,兩個以上*不能連續出現)
    如果是*,matrix[0][n]結果與matrix[0][n-2]結果相同
代碼如下:
令matrix[i][j]表示s的前i個字符[0,i)組成的subString,與p的前j個字符[0,j)組成的subString的匹配結果
 '''
matrix = [[False for i in range(n+1)] for i in range(m+1)]
'''
1、s和p都是null時,可以匹配,返回True
'''
matrix[0][0]=True
'''
2、 s為非null,p是null,永遠不匹配,返回False
3、 s為null,p為非null時,需要分情況:如果沒有*,則一定不能匹配;
    (注意:根據題意描述,我推斷: *不能是第一個字符,同時,兩個以上*不能連續出現)
    如果是*,matrix[0][n]結果與matrix[0][n-2]結果相同
'''
for i in range(2,n+1):
    if(p[i-1] == '*'):                
         matrix[0][i] = matrix[0][i-2]

狀態轉移方程為:

  1. 如果s[i-1] == p[j-1] 或者 p[j-1] == "." 則: matrix[i][j] = matrix[i-1][j-1]
  2. 如果p[j-1] == "*" 則分2種情況:
    ?? 1. 如果 p[j-2] == s[i-1]或者p[j-2]=="."
    ???則 matrix[i][j] = {
    ????matrix[i][j-2] (此時表示前邊的字符出現0次)
    ????or matrix[i][j-1] (此時*表示前邊的字符出現1次)
    ????or matrix[i-1][j] (此時
    表示前邊的字符出現多次)
    ???}
    ?? 2. 如果 p[j-2]不是".",也不是s[i-1]
    ???則 matrix[i][j] = matrix[i][j-2]

完整python代碼

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        m = len(s)
        n = len(p)
        '''
        初始化遞推矩陣
        令matrix[i][j]表示s的前i個字符[0,i)組成的subString,與p的前j個字符[0,j)組成的subString的匹配結果
        '''
        matrix = [[False for i in range(n+1)] for i in range(m+1)]
        '''
        1、s和p都是null時,可以匹配,返回True
        '''
        matrix[0][0]=True
        '''
        2、 s為非null,p是null,永遠不匹配,返回False
        3、 s為null,p為非null時,需要分情況:如果沒有*,則一定不能匹配;
            (注意:根據題意描述,我推斷: *不能是第一個字符,同時,兩個以上*不能連續出現)
            如果是*,matrix[0][n]結果與matrix[0][n-2]結果相同
        '''
        for i in range(2,n+1):
            if(p[i-1] == '*'):                
                matrix[0][i] = matrix[0][i-2]
        '''
        狀態轉移公式:
        令matrix[i][j]表示s的前i個字符[0,i)組成的subString,與p的前j個字符[0,j)組成的subString是否匹配,則
        1、  如果s[i-1] == p[j-1] 或者 p[j-1] == "."   則: matrix[i][j] = matrix[i-1][j-1]
        2、  如果p[j-1] == "*" 則分2種情況: 
                1)如果 p[j-2] == s[i-1]或者p[j-2]=="." 
                  則 matrix[i][j] =( matrix[i][j-2](此時*表示前邊的字符出現0次)  
                  or matrix[i][j-1](此時*表示前邊的字符出現1次)
                  or matrix[i-1][j](此時*表示前邊的字符出現多次)    )
                2)如果 p[j-2]不是".",也不是s[i-1]
                  則 matrix[i][j] = matrix[i][j-2]

        '''      
        for i in range(1, m+1):
            for j in range(1, n+1):
                if( p[j-1]=="." or s[i-1] == p[j-1] ):
                    matrix[i][j] = matrix[i-1][j-1]
                elif ( p[j-1] == "*" ):
                    if ( p[j-2]=="." or p[j-2]==s[i-1] ):
                        matrix[i][j] = ( matrix[i][j-1] or matrix[i][j-2] or matrix[i-1][j])
                    else :
                        matrix[i][j] = matrix[i][j-2]


        return matrix[m][n]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。