1

leetcode上面的题目解题及重构
题干:给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。

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

匹配应该覆盖整个字符串 (s) ,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
题目及示例传送门

如果直接用re,那这题就没意义了,所以肯定要自己写匹配算法
第一次成功提交代码:

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库中的匹配函数,心里略微平衡了一点

把别人提交的效率最高的代码贴出来:

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]

执行只用36ms


关翔宇
10 声望3 粉丝

即使是一只蜗牛,不停努力的奔跑,也能到达目标