ericpuwang

正则表达式匹配

给你一个字符串s和一个字符规律p,请你来实现一个支持'.''*'的正则表达式匹配

示例1

输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串

示例2

输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次

示例3

输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')

提示

题解

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        m, n = len(s) + 1, len(p) + 1
        # 为便于状态更新,减少对边界的判断,初始二维dp数组维度为(m+1)×(n+1)
        # 其中第一行和第一列的状态分别表示字符串s和p为空时的情况。
        dp = [[False] * n for _ in range(m)]
        dp[0][0] = True # 标识两个空字符串能够匹配
        for j in range(1, n):
            if p[j-1] == '*':
                dp[0][j] = dp[0][j-2]

        for i in range(1, m):
            for j in range(1, n):
                if s[i-1] == p[j-1] or p[j-1] == '.':
                    dp[i][j] = dp[i-1][j-1]
                elif p[j-1] == '*': # 首字符不为*,则此处j>=2
                    dp[i][j] = dp[i][j-2] # *号复制前面字符零次
                    if s[i-1] == p[j-2] or p[j-2] == '.': # *号复制前面字符k(k>0)次
                        dp[i][j] |= dp[i-1][j]

        return dp[-1][-1]