Leetcode做题日记:44. 通配符匹配(PYTHON)

本文深入探讨了通配符匹配算法,特别是如何处理‘?’和‘*’的复杂匹配情况,通过动态规划方法提供了有效的解决方案,附带详细代码解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个字符串 (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

最近考试周,发现不会动态规划做不了题,遂抽时间学一下,这两天只做了一道题

第一次的代码,想通p来吻合s,想通过p[i]是"星"还是’?'来改变指针i和s1,如果遇到"星?"组合需要接着移动指针i,当遍历完p之后如果也恰好遍历完s,那么返回True
但是失败了
我再一次吐槽这个编辑器,我想打两个**,编辑器自动变成斜体,晕死

	i=0
        s1=0
        k=0
        if len(s)==0 or len(p)-len(s)>=2:
            return False
        while i<len(p):
            if p[i]=='?':
                i+=1
                s1+=1
            elif p[i]=='*':
                if i==len(p)-1:
                    return True
                else:
                    j=1
                    
                    while p[i+j]=='*' or p[i+j]=='?':
                        j=j+1
                        if i+j==len(p)-1:
                            break
                    i+=j
                    s1+=1
                    if p[i] in s[s1:]:
                        for k in range(len(s[s1:])):
                            if s[s1+k]==p[i]:
                                s1+=k
                                break              
                    else:
                        return False
            elif p[i]==s[s1]:
                i+=1
                s1+=1
            else:
                return False
            if s1==len(s) and i!=len(p):
                return False
        
        if s1==len(s):
            return True 
        else:
            return False

学习了一下动态规划,找到答案了
我一开始也不会,学了很久,也分享一下我对这题的经验
首先,我先讲一下答案的含义,再看代码才能看懂
我以s=‘adceb’,p=’ * b *b’为例,并且我已经填了正确的dp表

在这里插入图片描述
注意看,dp表是多出来一行,和一列的,每一个值的含义,不代表这个s[i],p[j]是否对应,而是代表dp表的i-1行,j-1列构成的子表的答案,既然是动态规划解这题,那么我们要做的就是传递答案,第一个dp[0][0]为True,表示s,p都为零时的答案,这就是dp表的含义。既然我们是动态规划,那么我们是一点一点的加入p值,再加入a值,在我们填写(1,2)这个True时,要注意,既然是动态规划,那我们就是动态建设dp表,此时我们只考虑s=’’,p=’*'这个子序列,所以(1,2)为True
然后p再加一位继续判断,这个意思,直到p加载完判断之后,我们将s在加一位,重新判断下一排的表

	ls=len(s)
        lp=len(p)
        #首先制作动态规划表
        dp=[[False for i in range(lp+1)]for j in range(ls+1)] 
        
        #如果s.p都空,那么dp表只有True了,返回True
        dp[0][0]=True 
        #首先填写第一行,当p为星号时,即当p的子串最后一个为星时,记为True
        for i in range(1,lp+1):
            if p[i-1]=='*':
        #为什么要用i-1,j-1呢,因为我们填表是填(传递)答案,判断字符要判断答案之前的两个子序列    
                dp[0][i]=dp[0][i-1]
        #开始正是填写,首先从s取一位,开始判断dp表,答案是第二排
    
        for i in range(1,ls+1):
            for j in range(1,lp+1):
                if p[j-1]=='*':
                    dp[i][j]=dp[i][j-1] or dp[i-1][j]
        #这里为什么可以继承两个值呢,第一个表示星包含此此时s列加入的这个字母
        #第二个表示 星 代表空字符,即多了个星出来,那么这个星代表空字符            
                else:
                    dp[i][j]=(s[i-1]==p[j-1] or p[j-1]=='?') and dp[i-1][j-1]
        #这里第一项好理解,第二项什么意思呢?
        #指的是前序要True,那么当前s,p才能True
        #如果前面都不对,即使当前匹配又有什么用呢            
        return dp[ls][lp]
        #返回答案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值