原題地址:https://oj.leetcode.com/problems/regular-expression-matching/java
題意:python
Implement regular expression matching with support for '.'
and '*'
.c++
'.' 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
解題思路:正則表達式匹配的判斷。網上不少的解法是用遞歸作的,用java和c++均可以過,但一樣用python就TLE,說明這道題其實考察的不是遞歸。而是動態規劃,使用動態規劃就能夠AC了。這裏的'*'號表示重複前面的字符,注意是能夠重複0次的。正則表達式
先來看遞歸的解法:express
若是P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失敗;spa
若是P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。prototype
匹配成功的條件爲S[i]=='\0' && P[j]=='\0'。code
代碼,TLE:blog
class Solution: # @return a boolean def isMatch(self, s, p): if len(p)==0: return len(s)==0 if len(p)==1 or p[1]!='*': if len(s)==0 or (s[0]!=p[0] and p[0]!='.'): return False return self.isMatch(s[1:],p[1:]) else: i=-1; length=len(s) while i<length and (i<0 or p[0]=='.' or p[0]==s[i]): if self.isMatch(s[i+1:],p[2:]): return True i+=1 return False
再來看動態規劃的解法。遞歸
代碼:
class Solution: # @return a boolean def isMatch(self, s, p): dp=[[False for i in range(len(p)+1)] for j in range(len(s)+1)] dp[0][0]=True for i in range(1,len(p)+1): if p[i-1]=='*': if i>=2: dp[0][i]=dp[0][i-2] for i in range(1,len(s)+1): for j in range(1,len(p)+1): if p[j-1]=='.': dp[i][j]=dp[i-1][j-1] elif p[j-1]=='*': dp[i][j]=dp[i][j-1] or dp[i][j-2] or (dp[i-1][j] and (s[i-1]==p[j-2] or p[j-2]=='.')) else: dp[i][j]=dp[i-1][j-1] and s[i-1]==p[j-1] return dp[len(s)][len(p)]