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