面试题19. 正则表达式匹配(hard)

给定一个字符串 (s) 和一个字符模式 §。实现支持 ‘.’ 和 ‘*’ 的正则表达式匹配。

‘.’ 匹配任意单个字符。
‘*’ 匹配零个或多个前面的元素。
匹配应该覆盖整个字符串 (s) ,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
示例 1:

思路1:递归

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        # 若p为空,返回s是否为空
        # 若p为空,s不为空,匹配失败;s为空,匹配成功
        if not p:
            return not s
        # 定义first表示p和s的第一位是否匹配成功,匹配条件为p,s不为空 and p[0]==s[0]或“.”
        # 函数bool(s) 用于将给定参数s转换为布尔类型,如果没有参数,返回 False
        first = bool(s) and p[0] in {s[0], '.'}
        # 若p有*(p的长度>=2,p[1]==“*”,说明p的第二位是*,且*前有字符与之匹配)
        if len(p)>=2 and p[1] == "*":
        # 两种情况:
        # 第一:跳过这两个字符,x*表示x这个字符出现了0次(即没有字符x)
        # 第二:首位匹配成功,继续匹配s[1:]和p,即返回first and isMatch(s[1:],p[1:])
            return self.isMatch(s,p[2:]) or pre and self.isMatch(s[1:], p)
        else:
            return first and self.isMatch(s[1:],p[1:])    

思路2:动态规划

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        # 初始化sss的长度S,ppp的长度P
        S = len(s)
        P = len(p)
        # 初始化哈希表memo = {}
        memo = {}

        # memo键为(i,j),值为True or False,表示s[0, ..., i]和p[0, ..., j]是否匹配

        # 定义递归函数dp(i, j),i为当前s的匹配位置,j为p的匹配位置。
        def dp(i, j):
            # 若(i,j)出现在memo中,表示当前子问题,之前已经处理过,直接返回对应的值,memo[(i,j)]
            if ((i, j) in memo):
                return memo[(i, j)]
            # 若j == P,说明p已经匹配完,若此时s还有字符未匹配,则返回False,若s也匹配完,则返回True。即返回i == S
            if (j == P):
                return i == S

            # 定义pre表示当前p和s的首位是否匹配。条件:i < S 表示s是否遍历完。且p[j]是否等于s[i]或"."。
            pre = i < S and p[j] in {s[i], "."}

            # 判断是否存在 * 字符,条件:j <= P−2表示是否还剩两个字符以上,且p[j + 1]为 *:
            if (j <= P - 2 and p[j + 1] == "*"):
                # 跳过这两个字符,表示匹配0次,dp(i,j+2) 或者 首位匹配成功,继续匹配下一位
                tmp = dp(i, j + 2) or pre and dp(i + 1, j)
            else:
                # 否则,tmp=dp(i+1,j+1)
                tmp = pre and dp(i + 1, j + 1)
                
            # 更新memo,memo[(i, j)] = tmp
            memo[(i, j)] = tmp
            # 返回tmp
            return tmp

        # 返回dp(0, 0)
        return dp(0, 0)

发布了88 篇原创文章 · 获赞 31 · 访问量 5073

猜你喜欢

转载自blog.csdn.net/weixin_43455338/article/details/104884147