剑指 Offer 19. 正则表达式匹配

126 阅读1分钟

题目链接

说明

  • p= a\*b\*, s = abbb 为例
  • 下图为dp的矩阵,第一列和第一行用于帮助后续的状态转移,无实际含义 dp示意图
  1. rows = len(s)+1, cols = len(p)+1
  2. dp[rows][cols], dp[0][0] = True
  3. dp的第0行要初始化,为了后续的状态转移: 找到模式串的第一个*,此处的dp状态与* 的前面两个字符的dp状态相同
    for i in range(1, cols):
      if p[i-1] == '*':
          dp[0][i] = dp[0][i-2]
    

思路

  1. s[i-1] == p[j-1] or p[j-1] == '.' 则: dp[i][j] = dp[i-1][j-1]
  2. p[j-1] == '*' 则:
    • if s[i-1] != p[j-2] : dp[i][j] = dp[i][j-2]
    • if s[i-1] == p[j-2] or p[j-2] == '.' : dp[i][j] = dp[i-1][j] or dp[i][j-1]

代码实现

	class Solution:
      def isMatch(self, s: str, p: str) -> bool:
          rows = len(s)+1
          cols = len(p)+1
          dp = [[False for _ in range(cols)] for _ in range(rows)]
          dp[0][0] = True
          for i in range(1, cols):
              if p[i-1] == '*':
                  dp[0][i] = dp[0][i-2]
          for i in range(1, rows):
              for j in range(1, cols):
                  if s[i-1] == p[j-1] or p[j-1] == '.':
                      dp[i][j] = dp[i-1][j-1]
                  elif p[j-1] == '*':
                      if s[i-1] != p[j-2] and p[j-2] != '.':
                          dp[i][j] = dp[i][j-2]
                      else: 
                          if s[i-1] == p[j-2] or p[j-2] == '.':        
                              dp[i][j] = dp[i-1][j] or dp[i][j-1]
                          dp[i][j] |= dp[i][j-2]
                  else: dp[i][j] = False
          return dp[rows-1][cols-1]