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 *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:

Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4:

Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".

Example 5:

Input:
s = "mississippi"
p = "mis*is*p*."
Output: false

https://buptwc.github.io/2018/10/18/Leetcode-10-Regular-Expression-Matching/

https://www.cnblogs.com/grandyang/p/4461713.html

下面的是我原来的代码,想法就是首先如果p为空,那么只有s为空才正确;p为一位,那么不能为“*”,为“.”的时候,s可以是任意的字母,为通常字母时,s应为对应的字母;两位以上根据第二个字母是不是*再分类,代码如下

class Solution:
    def getLengthBeginSame(self, s, p):
        """
        p是一个单字母或者".",s是一个字符串
        求s开头有多少个重复的p
        """
        length = 0
        for i in s:
            if i == p or p == ".":
                length += 1
            else:
                break
        return length

    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if len(p) == 0:
            return not s

        if p[0] == "*":
            return False

        if len(p) == 1:
            return len(s)==1 and (p == "." or p == s)

if p[1] == "*": len_beginsame = self.getLengthBeginSame(s, p[0]) for i in range(len_beginsame, -1, -1): if self.isMatch(s[i:], p[2:]): return True return False if len(s)>0 and (p[0] == s[0] or p[0] == "."): return self.isMatch(s[1:], p[1:]) return False

想了一想应该是犯了斐波拉契数列的相关算法题(跳楼梯,锯木头之类的)的问题,有很多重复计算,规划一下动态规划可能会好很多。

既然如此可以放一个集合来存储不成功的情况,因为我原来写的有成功的就直接true,所以只要存储不成功的情况,

假定集合中有元素(m,n),则表示s后m位和p后n位不匹配,只要在原来return False的地方之前加入集合即可,代码如下

class Solution:
    def __init__(self):
        #记载不匹配的集合,元素是元组,(m,n):表示s后m位和p后n位不匹配
        self.set_notmatch = set()
    def getLengthBeginSame(self, s, p):
        """
        p是一个单字母,s是一个字符串
        求s开头有多少个重复的p
        """
        length = 0
        for i in s:
            if i == p or p == ".":
                length += 1
            else:
                break
        return length

    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        len_s = len(s)
        len_p = len(p)

        if (len_s, len_p) in self.set_notmatch:
            return False

        if not p:
            if not s:
                return True
            self.set_notmatch.add((len_s, len_p))
            return False

        if p[0] == "*":
            return False

        if len_p == 1:
            if len_s == 1 and (p == "." or p == s):
                return True
            self.set_notmatch.add((len_s, len_p))
            return False

        if p[1] == "*":
            len_beginsame = self.getLengthBeginSame(s, p[0])
            for i in range(len_beginsame, -1, -1):
                if (len_s-i, len_p-2) in self.set_notmatch:
                    continue
                if self.isMatch(s[i:], p[2:]):
                    return True
                # self.set_notmatch.add((len_s - i, len_p - 2))
            self.set_notmatch.add((len_s, len_p))
            return False
            
        if len(s)>0 and (p[0] == s[0] or p[0] == "."):
            if (len_s-1, len_p-1) in self.set_notmatch:
                return False
            return self.isMatch(s[1:], p[1:])
        return False

if __name__ == "__main__":
    classa = Solution()
    # s = "aaaaabaccbbccababa"
    # p = "a*b*.*c*c*.*.*.*c"
    s = "abca"
    p = "a*ab*bc*ca*as*b*a"

    print(classa.isMatch(s, p))
    print(classa.set_notmatch)
    # print(classa.getLengthBeginSame("aba", p[1]))        

这下过了,

不过也可以放一个二维列表来存储成功与否的情况,没有很多次的迭代,不知道是否会快一点

 

posted @ 2018-10-30 15:49  茫茫碧落  阅读(233)  评论(0编辑  收藏  举报