leetcode hard 10. 正则表达式匹配

https://leetcode-cn.com/problems/regular-expression-matching/

思路:动态规划

  1. dp:(len(s) +1)* (len(p) + 1)
  2. dp[ii][jj]代表s[0,i-1]和p[0,j-1]是否匹配,故有ii=i+1,jj=j+1。也就是说i,j对应比较时候改变的是dp[i+1][j+1]时的位置。
  3. 边界情况,s='',需要先把第一行初始化,这时候就是下面的特殊情况,即当p[j]=='*'时,s[i]!=p[j-1],dp[ii][jj] = dp[ii][jj-2]。
  4. 先分两类:
  • s[i]==p[j],(或p[j]=='.')dp[ii][jj] = dp[ii-1][jj-1],当前两个字符相等,只需要各退一步看是否相等。
  • s[i]==p[j],p[j]=='*',再分两大类。为了简便,设置Sx,Pzy,y='*'。
  • s[i]!=p[j-1],即x!=z,则Sx必须和P匹配,dp[ii][jj] = dp[ii][jj-2]
  • s[i]==p[j-1],即x==z,分几种匹配情况。
  • Sx和P匹配,x和z*匹配,dp[ii][jj] = dp[ii][jj-2]
  • Sx和Pz匹配,''和*匹配,dp[ii][jj] = dp[ii][jj-1]
  • S和P匹配,x和z*匹配,dp[ii][jj] = dp[ii-1][jj-2]
  • S和Pz匹配,x和*匹配,dp[ii][jj] = dp[ii-1][jj-1]
  • S和Pz*匹配,x和*匹配,dp[ii][jj] = dp[ii-1][jj]

代码

class Solution(object):
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if len(s) == 0 and len(p) == 0: return True
        dp = []
        for i in range(len(s) + 1):
            dp.append([0] * (len(p) + 1))
        dp[0][0] = 1

        for j in range(len(p)):
            ii, jj = 0, j + 1
            if p[j] == '*':
                if j > 0:
                    dp[ii][jj] = dp[ii][jj - 2]
        for i in range(len(s)):
            for j in range(len(p)):
                ii, jj = i + 1, j + 1
                if s[i] == p[j] or p[j] == '.':
                    dp[ii][jj] = dp[ii - 1][jj - 1]
                else:
                    if p[j] == '*':
                        if j > 0 and (s[i] == p[j - 1] or p[j - 1] == '.'):
                            dp[ii][jj] = max(dp[ii - 1][jj], dp[ii - 1][jj - 1], dp[ii - 1][jj - 2], dp[ii][jj - 2],
                                             dp[ii][jj - 1])
                        elif j > 0 and s[i] != p[j - 1] and p[j - 1] != '.':
                            dp[ii][jj] = dp[ii][jj - 2]

        return dp[-1][-1] == 1