zoukankan      html  css  js  c++  java
  • 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]))        

    这下过了,

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

  • 相关阅读:
    LeetCode解题报告—— Permutations & Permutations II & Rotate Image
    LeetCode解题报告—— Combination Sum & Combination Sum II & Multiply Strings
    LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
    顺利通过EMC试验(2)
    CSS复合选择器
    Emmet快速生成HTML和CSS
    Spring 三种创建Bean的方式
    Spring BeanFactory和ApplicationContext的区别
    Spring ApplicationContext的三个实现类详解
    CSS的引入方式
  • 原文地址:https://www.cnblogs.com/mangmangbiluo/p/9877270.html
Copyright © 2011-2022 走看看