leetcode里一道hard难度的题(第10题),
题主已经栽死在里面,借鉴了别人优秀的思想用python实现了,经典的东西要保留。
感谢@Vosky,出处链接http://blog.csdn.net/hk2291976/article/details/51165010
题目描述:
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).
The function prototype should be:
bool isMatch(const char *s, const char *p)Some examples:
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aaa”,”aa”) → false
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
这题最难的就是对‘*’的判断,情况多到超出你我想象,
但是有一点,”*”不会单独出现,它一定是和前面一个字母或”.”配成一对。看成一对后”X*”,它的性质就是:要不匹配0个,要不匹配连续的“X”。
题目的关键就是如何把这一对放到适合的位置。
考虑一个特殊的问题:
情况1:
“aaaaaaaaaaaaaaaa”
“a*aa*”
情况2:
“aaaaaaaaaaaaaaaa”
“a*ab*”
在不知道后面的情况的时候,我如何匹配a*?
-
最长匹配
显然不合适,这样后面的a就无法匹配上了 -
匹配到和后面长度一样的位置,比如情况1,就是留3个a不匹配,让后面3个字母尝试去匹配。
这样看似合适,但是遇到情况2就不行了。 - 回溯,每种”*”的情况,看哪种情况能成功,如果其中出现了问题,马上回溯,换下一种情况
下面题主考虑两种方法。(DP太难,题主已弃)
如果“*”不好判断,那我大不了就来个暴力的算法,把“*”的所有可能性都测试一遍看是否有满足的,用两个指针i,j来表明当前s和p的字符。
我们采用从后往前匹配,为什么这么匹配,因为如果我们从前往后匹配,每个字符我们都得判断是否后面跟着“*”,而且还要考虑越界的问题。但是从后往前没这个问题,一旦遇到“*”,前面必然有个字符。
如果j遇到 ”*”,我们判断s[i] 和p[j-1]是否相同,
如果相同我们可以先尝试匹配掉s的这个字符,i–,然后看之后能不能满足条件,满足条件,太棒了!我们就结束了,如果中间出现了一个不满足的情况,马上回溯到不匹配这个字符的状态。
不管相同不相同,都不匹配s的这个字符,j-=2 (跳过“*”前面的字符)
还是递归哦
if ((i > -1) and (p[j-1] == '.' or p[j-1] == s[i])):
if (self.myMatch(s,i-1,p,j)):
return True
else:
return self.myMatch(s,i,p,j-2)
如果j遇到的不是“*”,那么我们就直接看s[i]和p[j]是否相等,不相等就说明错了,返回。
if (p[j] == '.' or p[j] == s[i]):
return self.myMatch(s,i-1,p,j-1)
再考虑退出的情况
如果j已经<0了说明p已经匹配完了,这时候,如果s匹配完了,说明正确,如果s没匹配完,说明错误。
如果i已经<0了说明s已经匹配完,这时候,s可以没匹配完,只要它还有”*”存在,我们继续执行代码。
class Solution(object):
def isMatch(self, s, p):
return self.myMatch(s,len(s)-1,p,len(p)-1)
def myMatch(self, s, i, p, j):
if j == -1:
if i == -1:
return True
else:
return False
if (p[j] == '*'):
if ((i > -1) and (p[j-1] == '.' or p[j-1] == s[i])):
if (self.myMatch(s,i-1,p,j)):
return True
else:
return self.myMatch(s,i,p,j-2)
if (p[j] == '.' or p[j] == s[i]):
return self.myMatch(s,i-1,p,j-1)
return False
二、用python正则库re直接解决
import re
class Solution(object):
def isMatch(self,s,p):
return re.match(p,s) != None