LeetCode 10. 正则表达式匹配 44. 通配符匹配 (动态规划)

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

‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

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

示例 1:
输入: s = “aa” p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。

示例 2:

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

示例 3:

输入: s = “ab” p = “.*”
输出: true

解释: "." 表示可匹配零个或多个(’’)任意字符(’.’)。

示例4:
输入: s = “aab” p = “cab”
输出: true
解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个,
‘a’ 被重复一次。因此可以匹配字符串 “aab”。

示例 5:
输入: s = “mississippi” p = “misisp*.”
输出: false

题解: 因为存在*字符多匹配,因此考虑倒序匹配,并用数组记录,从记录的结果中递推最优解,保证可行解中的TRUE能被传递下来.

首先考虑若不存在*时,只有 . 存在,那么字符串长度一定要匹配,接着就是对应位置的字符是否相等或等于 . 了

当条件中给了*多匹配时,我们考虑对匹配串中的每一位找到模式串中对应的位置,在匹配过程中,fm即表示当前模式串与匹配串中的哪些位置能成功匹配,每一位匹配的是字符本身或 . 视为该位置匹配成功,但是仍不能作为连续匹配成功的依据.

之后将判断匹配串中此时的之后一位是否是 *
若是 * 则判断 当前字符i 以及之后的 * 再之后的串是否成功匹配, 若成功匹配则继承下来,形成一段连续匹配成功的串.
当无法从当前这一轮延续成功的匹配结果时,就判断能否使用上一轮的匹配结果进行延续,即dp[i+1][j]

当下一位不是 * 时,不能连续匹配多个重复字符, 表示必须以一一对应的方式匹配,直接从上一轮该位置之后的位置继承匹配结果.

class Solution:
    def isMatch(self, text, pattern):
        dp=[[False]*(len(pattern)+1) for i in range(len(text)+1)]
        dp[-1][-1]= True
        for i in range(len(text),-1,-1):
            for j in range(len(pattern)-1,-1,-1):
                fm = i < len(text) and pattern[j] in (text[i],'.')
                if j+1 < len(pattern) and pattern[j+1]=='*':
                    dp[i][j]=dp[i][j+2] or fm and dp[i+1][j]
                else:
                    dp[i][j]=fm and dp[i+1][j+1]
        return dp[0][0]

给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。

‘?’ 可以匹配任何单个字符。 ‘*’ 可以匹配任意字符串(包括空字符串)。 两个字符串完全匹配才算匹配成功。
说明:
s 可能为空,且只包含从 a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。

示例 1:
输入: s = “aa” p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。

示例 2:
输入: s = “aa” p = “*”

输出: true
解释: ‘*’ 可以匹配任意字符串。

示例 3:

输入: s = “cb” p = “?a”
输出: false
解释: ‘?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。

示例 4:
输入: s = “adceb” p = “ab”
输出: true
解释: 第一个 ‘’ 可以匹配空字符串, 第二个 '’ 可以匹配字符串 “dce”.

示例 5:
输入: s = “acdcb” p = “a*c?b”
输入: false

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        import ujson
        dp=[[False]*(len(p)+1) for i in range(len(s)+1)]
        dp[-1][-1]= True
        for i in range(len(s),-1,-1):
            for j in range(len(p),-1,-1):
                if i==len(s) and j==len(p):continue
                fm = i < len(s) and j< len(p) and p[j] in (s[i],'?','*')
                if j < len(p) and p[j]=='*':
                    dp[i][j]=dp[i][j+1] or fm and dp[i+1][j]
                else:
                    dp[i][j]=fm and dp[i+1][j+1]
        return dp[0][0]
原文地址:https://www.cnblogs.com/kuronekonano/p/11794304.html