解法
完全是考虑细心和剪枝
假设连续的*
都被压缩成了一个
中心思想是,?和普通字符的匹配没问题,但是*的匹配可以如下快进处理:
假设目前匹配到s[i]
和p[j]
,其中p[j]为*
,s上的下一个匹配位点至少从s[i+1]以后的第一个和p[j+1]相同的字符开始
为了加速匹配,可以把p按字符*
分开成若干个普通字符组patterns
它们总的长度为字符串最小需要的长度
patterns[0]
必须完全跟开头匹配patterns[j] (j>0, 如果存在)
则可以跳过任意字符进行匹配
solve(i,j)
把s[i:]
和patterns[j:]
进行匹配的结果
- 如果
patterns[j:]
加起来的长为0,说明可以匹配任意字符串:返回真 - 如果j是最后一个,要把
patterns[j]
与字符串s[i:]
的尾部进行匹配,成则成不成则败 - 否则,如果
patterns[j]
不为空(为空则跳过)
找到s上第一个使得patterns[j]
完全匹配的位置,再往后匹配s[i+len(patterns[j]):]
和patterns[j+1:]
继续再减小时间复杂度可以使用kmp进行匹配
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
patterns = p.split('*')
np = len(patterns)
ns = len(s)
if p=="":
return ns == 0
def normal_match(s,p):
if len(s)!=len(p):
return False
n = len(s)
for i in xrange(n):
if s[i]!=p[i] and p[i]!='?':
return False
return True
def solve(i,j):
if j>=np:
return i>=ns
min_length = len("".join(patterns[j:]))
nj = len(patterns[j])
if nj==0:
return True if j==np-1 else solve(i,j+1)
if j==np-1:
return normal_match(s[max(i,len(s)-nj):], patterns[j])
while ns-i>=min_length and not normal_match(s[i:i+nj],patterns[j]):
i += 1
if ns-i<min_length:
return False
return solve(i+nj, j+1)
if ns == 0:
return "".join(patterns) == ""
if not normal_match(s[:len(patterns[0])], patterns[0]):
return False
if np==1:
return len(patterns[0])>=ns
return solve(len(patterns[0]), 1)