给定一个字符串 (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]
#返回答案