1@TOC
Regular Expression Matching
题目描述
就是看某个字符串s能够满足简化版的正则表达式p。p只支持’.’、’’、以及’a-z’这些字符,’.‘表示匹配任意单个字符。’'表示匹配零个或多个前面的那一个元素。
题目分析
该题目一看就满足最优子结构性质,所以找下状态转移方程即可使用动态规划的方式来做了。假设dp[i][j]表示s[:i+1]到p[:j+1]是否满足匹配关系。那么只要p[j]为’.‘则只要dp[i-1][j-1]满足条件那么dp[i][j]也能满足条件。或者p[j]为’’, p[j-1]为’.‘那么只要dp[i][j-2]满足条件,那么p[N][j]也能满足条件(N>=i),如果p[j]为’‘但是p[j]不为’.’,则只要dp[i][j-2]满足条件,那么p[N][j]也能满足条件(N >= i 并且从s[i]到s[N]的字符都是为p[j-1])。
代码如下
func isMatch(s string, p string) bool {
if len(p) > 0 && p[0] == '*' {
return false
}
lenS := len(s)
lenP := len(p)
dp := make([][]bool, lenS + 5)
for i := range dp {
dp[i] = make([]bool, lenP + 5)
}
dp[0][0] = true
s = "0" + s + "0"
p = "0" + p + "0"
var i, j, k int
for j = 1; j <= lenP; j++ {
for i = 1; i <= lenS+1; i++ {
if p[j] == '.' {
if dp[i-1][j-1] {
dp[i][j] = true
}
}else if p[j] == '*' && p[j-1] == '.' {
if dp[i-1][j-2] {
for k = i-1; k <= lenS; k++ {
dp[k][j] = true
}
break
}
}else if p[j] == '*' {
if dp[i-1][j-2] {
dp[i-1][j] = true
for k = i; k <= lenS; k++ {
if s[k] == p[j-1] {
dp[k][j] = true
}else {
break
}
}
i = k
}
}else if p[j] == s[i] && dp[i-1][j-1] {
dp[i][j] = true
}
}
}
return dp[lenS][lenP]
}
其他
- leetcode上面还有根据dp[i][j]的状态推到dp[i][j]后面的匹配关系,看起来实现比较简单。
- 网上还有种状态机的实现方法,但是没仔细看,估计是可行的。