正則表達式匹配

leetcode上面的題目解題及重構
題幹:給定一個字符串 (s) 和一個字符模式 (p)。實現支持 '.' 和 '*' 的正則表達式匹配。正則表達式

'.' 匹配任意單個字符。 
 '*' 匹配零個或多個前面的元素。

匹配應該覆蓋整個字符串 (s) ,而不是部分字符串。
說明:
s 可能爲空,且只包含從 a-z 的小寫字母。
p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。
題目及示例傳送門算法

若是直接用re,那這題就沒意義了,因此確定要本身寫匹配算法
第一次成功提交代碼:express

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if p == '':
            return s == ''
        if len(p) == 1:
            return len(s) == 1 and (s == p or p == '.')
        if p[1] != '*':
            if s == '':
                return False
            return (p[0] == s[0] or p[0] == '.') and self.isMatch(s[1:], p[1:])
        while s and (p[0] == s[0] or p[0] == '.'):
            if self.isMatch(s, p[2:]):
                return True
            s = s[1:]
        return self.isMatch(s, p[2:])

執行用時:1100 ms,執行效率算不好,只超過了32%的提交效率
優化後第二次提交:函數

def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if p == "":
            return s == ""
        if len(p) == 1:
            return False if len(s) != 1 else (s == p or p == "." or p == "*")
        if (p[-1] != '*') and (p[-1] != '.') and (p[-1] not in s): 
            return False 
        if (p[1] != '*'): 
            return s != '' and (p[0] == s[0] or p[0] == '.') and self.isMatch(s[1:], p[1:])
        else:
            while s and (p[0] == s[0] or p[0] == '.'):
                if self.isMatch(s, p[2:]):
                    return True
                s = s[1:]
            return self.isMatch(s, p[2:])

執行用時間優化到140 ms,但也只超過了40%的提交效率。
不過查別人效率比我高的提交中,不少人用的是re庫中的匹配函數,內心略微平衡了一點優化

把別人提交的效率最高的代碼貼出來:code

class Solution(object):
    def isMatch(self, s, p, memo={("",""):True}):
        if not p and s:      return False
        if not s and p:      return set(p[1::2]) == {"*"} and not (len(p) % 2)
        if (s,p) in memo:    return memo[s,p]

        char, exp, prev = s[-1], p[-1], 0 if len(p) < 2 else p[-2]
        memo[s,p] =\
               (exp == '*' and ((prev in {char, '.'} and self.isMatch(s[:-1], p, memo)) or self.isMatch(s, p[:-2], memo)))\
               or\
               (exp in {char, '.'} and self.isMatch(s[:-1], p[:-1], memo))
        return memo[s,p]

執行只用36msleetcode

相關文章
相關標籤/搜索