您的位置:首页 > 其它

LeetCode - Regular Expression Matching

2015-04-17 20:19 316 查看

LeetCode - Regular Expression Matching

The Problem is described as following:

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(“aa”, “.*”) → true

isMatch(“ab”, “.*”) → true

isMatch(“aab”, “c*a*b”) → true

整体来说,这道题目具有一定的难度,起初我采用的是递归的解法,但是python写的代码会存在LTE的问题(貌似C++和Java可以AC),遂放弃,转而研究DP的解法,一下对两种方法均做简单说明

递归方法:

针对p的长度分三种情况讨论:

len(p)==0时,当且仅当s长度为0输出True;

len(p)==1时,当且仅当s长度为1且字符相等(注意p[0]=’.’的情况),输出True;

len(p)>1时,需要根据p[1]是否为*,再作区分:

p[1]!=’*’ 时,这一情况较为简单,若s[0]!=p[0],输出False,否则字符去掉前一位继续比较;

p[1]==’*’,因为不确定星号以及其之前的元素出现次数,就需要针对s中到底有多少位被抵消,分别展开讨论,会带来较大的时间消耗,想必这也就是python代码AC不过的原因,

# Solution version 1
# TLE when input:  "baccbbcbcacacbbc", "c*.*b*c*ba*b*b*.a*"
class Solution:
# @param s, a string
# @param p, a string
# @return a boolean
def isMatch(self, s, p):
# len == 0
if len(p) == 0:
return len(s) == 0
# len == 1
if len(p) == 1:
return (len(s) == 1) and (s[0] == p[0] or p[0] == '.')
# len > 1 ,next char is '*'
if p[1] != '*':
if len(s) == 0:
return False
else:
return (s[0] == p[0] or p[0] == '.') and (self.isMatch(s[1:],p[1:]))
# next char is '*', more complicated
while (len(s) > 0) and (s[0] == p[0] or p[0] == '.'):
if self.isMatch(s, p[2:]):
return True
s = s[1:]
return self.isMatch(s,p[2:])


动态规划:

这一部分思路参考此博客

思路是使用bool类型的二维数组dp[m+1][n+1](m、n分别为字符串s和p的长度)记录s和p是否匹配,即dp[i+1][j+1]表示s的前i个字符是否与p的前j的字符相匹配。

如果p[j]不等于‘*‘,则dp[i + 1][j + 1] = dp[i][j] && s[i] == p[j]

如果p[j]等于‘*‘,则当且仅当在下面三种情况为真,dp[i + 1][j + 1]为真:

‘*‘前面字符重复出现0次,则p字符串需要往前看2位,即dp[i + 1][j - 1]是否为真

‘*‘前面的字符重复出现1次,则p字符串只需要往前看1位,即dp[i + 1][j]是否为真

‘‘前面的字符重复出现次数大于1次,则s字符串需要往前看1位,即dp[i][j + 1]是否为真,以及s字符串当前字符(s[i])与p字符串‘‘前面字符(p[j - 1])是否相匹配。

# Solution Version 2 with DP . AC succeed .
class Solution:
# @param s, a string
# @param p, a string
# @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] == '*' and 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] == '.' or p[j-1] == s[i-1]:
dp[i][j] = dp[i-1][j-1]
elif p[j-1] == '*':
dp[i][j] = dp[i][j-2] or dp[i][j-1] or (dp[i-1][j] and (s[i-1] == p[j-2] or p[j-2] == '.'))
return dp[len(s)][len(p)]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode