44.通配符匹配 python

题目

题目描述

给你一个输入字符串 (s) 和一个字符模式 § ,请你实现一个支持 ‘?’ 和 ‘’ 匹配规则的通配符匹配:
‘?’ 可以匹配任何单个字符。
'
’ 可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。

示例 1:

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

示例 2:

输入:s = “aa”, p = ""
输出:true
解释:'
’ 可以匹配任意字符串。

示例 3:

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

提示:

0 <= s.length, p.length <= 2000
s 仅由小写英文字母组成
p 仅由小写英文字母、‘?’ 或 ‘*’ 组成

题解

通配符匹配问题可以通过动态规划(Dynamic Programming, DP)来高效解决。这个问题要求我们支持两种特殊字符:?*,其中 ? 可以匹配任何单个字符,而 * 可以匹配任意字符序列(包括空字符序列)。我们需要构建一个二维的DP表,用来记录子串之间的匹配状态。

动态规划解法

状态定义

  • dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。

初始化

  • dp[0][0] = True,表示空字符串与空模式是匹配的。
  • 如果模式 p 开头有 *,则 dp[0][j] (对于所有 j > 0)也可以为 True,因为 * 可以匹配空字符序列。

状态转移方程

  1. p[j-1] == '?' 或者 p[j-1] 是一个小写字母并且等于 s[i-1]
    • dp[i][j] = dp[i-1][j-1]
  2. p[j-1] == '*'
    • * 可以匹配空字符序列:dp[i][j] = dp[i][j-1]
    • * 可以匹配至少一个字符:dp[i][j] = dp[i-1][j]

结果

  • 最终的结果保存在 dp[m][n] 中,其中 mn 分别是字符串 s 和模式 p 的长度。

Python 实现代码

以下是按照上述思路实现的 Python 代码:

def isMatch(s: str, p: str) -> bool:
    m, n = len(s), len(p)
    
    # 创建DP表,并初始化
    dp = [[False] * (n + 1) for _ in range(m + 1)]
    dp[0][0] = True
    
    # 初始化第一行,处理模式中开头的'*'
    for j in range(1, n + 1):
        if p[j - 1] == '*':
            dp[0][j] = dp[0][j - 1]
    
    # 填充DP表
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if p[j - 1] == '?' or p[j - 1] == s[i - 1]:
                dp[i][j] = dp[i - 1][j - 1]
            elif p[j - 1] == '*':
                dp[i][j] = dp[i][j - 1] or dp[i - 1][j]
    
    return dp[m][n]

代码解释

  • 初始化:首先创建一个 (m+1) x (n+1) 大小的DP表,并将 dp[0][0] 设置为 True。然后检查模式 p 是否以 * 开始,如果是,则相应位置也设置为 True

  • 填充DP表:使用双重循环遍历字符串 s 和模式 p 的每一个字符。根据当前字符的不同情况(普通字符、?*),更新DP表中的值。

  • 结果:最终返回 dp[m][n] 的值,即整个字符串 s 和模式 p 是否完全匹配。

这种方法确保了我们可以有效地处理包含 ?* 的通配符匹配问题,并且能够应对题目中给出的最大输入规模(字符串和模式长度均不超过2000)。

提交结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gxls2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值