leetcode string match相关题目

1. Regular Expression Matching(https://oj.leetcode.com/problems/regular-expression-matching/)

解法一:递归

(1)当p[j+1] != '*'时, 若s[i] == p[j] 或p[j]=='.', 返回isMatch(i+1, j+1)。 若s[i] != p[j], return False

(2)当p[j+1] == '*'时,若s[i] == p[j], 则要看s[i]开始的字串,若s[i],s[i+1]....s[k]都等于p[j],则要分别判断isMathc(i, j+2), isMatch(i+1, j+2), isMath(i+2, j+2)...isMatch(k, j+2),因为b*指的是0个或多个b

python代码如下:

 1   def isMatch(self, s, p):
 2 
 3     def match(idxs, idxp):
 4       if idxp == len(p):
 5         return idxs == len(s)
 6 
 7       if idxp == len(p)-1 or p[idxp+1] != '*':
 8         if idxs == len(s) or (s[idxs] != p[idxp] and p[idxp] != '.'):
 9           return False
10         else:
11           return match(idxs+1, idxp+1)
12       else:
13         while idxs < len(s) and (s[idxs] == p[idxp] or p[idxp] == '.'):
14           if match(idxs, idxp+2):
15             return True
16           idxs += 1
17       return match(idxs, idxp+2)
18 
19     return match(0, 0)

会TLE,最差情况是指数级的时间复杂度

解法二:动态规划

维护一个布尔数组res[i][j]来代表s的前i个字符和p的前j个字符是否匹配,这里res的维度是s.length+1, p.length+1。需要考虑一下三种情况:

(1)p[j+1] != '*', 若s[i] == p[j]并且res[i][j] == true, 则res[i+1][j+1] = true否则res[i+1][j+1]=false

(2)p[j+1] == '*', 若p[j] == '.', 则只要有res[i+1][j] == true 或 res[i+1][j-1] == true, 则res[i+1][j+1], res[i+2][j+1]..res[s.length][j+1]都为true

(3)p[j+1] == '*', 若p[j] != '.', 则若满足以下任意一条,res[i+1][j+1]即为true

    (a) res[i+1][j-1] == true, ('*'前面一个字符都不取)

    (b) res[i+1][j] == true( '*'前取一个字符)

    (c) res[i][j+1] && s[i-1] == s[i] && s[i-1] = p[j-1](字符一直重复并且是'*'前面的那个字符)

 1   def isMatch(self, s, p):
 2     ls = len(s)
 3     lp = len(p)
 4     dp = [[False for i in range(lp+1)] for j in range(ls+1)]
 5 
 6     dp[0][0] = True
 7     for i in xrange(1, lp+1):
 8       if p[i-1] == '*':
 9         if i >= 2:
10           dp[0][i] = dp[0][i-2]
11 
12     for i in xrange(1, ls+1):
13       for j in xrange(1, lp+1):
14         if p[j-1] == '.':
15           dp[i][j] = dp[i-1][j-1]
16         elif p[j-1] == '*':
17           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] == '.'))
18         else:
19           dp[i][j] = dp[i-1][j-1] and s[i-1] == p[j-1]
20 
21     return dp[ls][lp]

时间复杂度O(m*n), 空间复杂度O(m*n)

2.wildcard-matching(https://oj.leetcode.com/problems/wildcard-matching/)

解法一:

(1)若s[i] == p[j]或p[j] == '?', 匹配, i和j都向前移一位,即i++, j++

(2)若p[j] == '*', 匹配,记录此时'*'的位置以及匹配的s的位置

(3)其他情况,则不匹配

    (a)判断之前是否出现过'*',若出现过,则将p的当前位置指向前一个'*'的位置的下一位,s的位置为之前记录位置的下一位,并且依然将此位置记录

    (b)若未出现过'*',则返回false

 (4)匹配到s末尾,若p仍然有剩余字符,判断剩余字符中如果仅存在'*'字符,返回True, 否则返回False

时间复杂度O(n)

 1   def isMatch(self, s, p):
 2     ls = len(s); lp = len(p)
 3     currP = -1; currS = 0
 4     idxs = 0; idxp = 0
 5     while idxs < ls:
 6       if idxp < lp and (s[idxs] == p[idxp] or p[idxp] == '?'):
 7         idxs += 1; idxp += 1
 8         continue
 9       if idxp < lp and p[idxp] == '*':
10         currP = idxp; currS = idxs; idxp += 1
11         continue
12       if currP != -1:
13         idxp = currP + 1; currS += 1; idxs = currS
14         continue
15       return False
16     while idxp < lp:
17       if p[idxp] != '*':
18         return False
19       idxp += 1
20     return True

 

posted @ 2014-10-25 01:08  darlwen  阅读(239)  评论(0编辑  收藏  举报