题目:
Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
.
Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Example 4:
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".
Example 5:
Input:
s = "mississippi"
p = "mis*is*p*."
Output: false
一开始看错题了:
以为模式 aa*bc*de* 的意思是 {[(aa)*n (bc)]*n (de)}*n 【备注:*n表示 重复n遍】
然后有了如下的代码:
class Solution:
def isMatch_without(self,s,p):
match = True
for i in range(len(s)):
if s[i] == p[i] or p[i]==".":
pass
else:
match = False
break
return match
def isMatch(self, s: str, p: str) -> bool:
# 边缘情况
if s == "":
if p == "":
return True
elif p[-1] == "*":
return True
else:
return False
match = True
ps = str.split(p, "*")
#如果不是以 * 结尾
if ps[-1] !="":
match = self.isMatch_without(s[-len(ps[-1]):],ps[-1])
if match:
s = s[:-len(ps[-1])]
else:
return False
ps.pop()
index_p = len(ps)
if index_p ==0 and s!="":
return False
while s!="":
if index_p>0:
index_p -=1
else:
index_p = len(ps)-1
if len(s) >= len(ps[index_p]):
match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
else:
match = False
if match:
while match & (s!=""):
s = s[:-len(ps[index_p])]
if len(s) >= len(ps[index_p]):
match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
else:
match = False
else:
index_p = len(ps) - 1
if len(s) >= len(ps[index_p]):
match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
else:
match = False
if not match:
return False
else:
while match & (s!=""):
s = s[:-len(ps[index_p])]
if len(s) >= len(ps[index_p]):
match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
else:
match = False
return True
结果发现题目没有那么复杂,
模式为 aa*bc*de*的意思是:
a (a)*n b (c)*n d (e)*n ,如此一来,这个变成了一个回溯题。对于 x* 模式需要分两步:
1、s不删x(x在s中重复0遍),模式p删除 x*判断能否走通;
2、若走不通 s中删除 x,模式p保留 x*判断能否走通(通过不断回溯,可以实现 s中删除 n遍x,p中删除 x*)
class Solution:
def isMatch(self, s: str, p: str) -> bool:
i = len(p)-1
while i >=0:
if p[i] == "*":
i -= 1
# 假设s中不包含 * 前面的字符,尝试看是否走得通
if self.isMatch(s,p[:i]):
return True
# 走不通,回溯,看能否删一个字符
else:
while len(s)>0:
if p[i]=="." or s[-1]==p[i]:
s = s[:-1]
if self.isMatch(s,p[:i]):
return True
else:
i -= 1
break
# 不含*的普通模式,没有分枝
else:
if len(s)>0:
if p[i]=="." or s[-1]==p[i]:
i -= 1
s = s[:-1]
else:
return False
else:
return False
if len(s) ==0:
return True
else:
return False
这个题必须用回溯,不用回溯,会有特别多边边角角的问题考虑不到。