题目
Given an input string (s
) and a pattern (p
), 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).
Note:
- s
could be empty and contains only lowercase letters a-z
.
- p
could be empty and contains only lowercase letters a-z
, and characters like .
or *
.
Example
s | p | Output | Explanation |
---|---|---|---|
‘aa’ | ‘a’ | False | “a” does not match the entire string “aa”. |
‘aa’ | ‘a*’ | True | ‘*’ means zero or more of the precedeng element, ‘a’. Therefore, by repeating ‘a’ once, it becomes “aa”. |
“ab” | “.*” | True | “.” means “zero or more () of any character (.)”. |
“aab” | “c*a*b” | True | c can be repeated 0 times, a can be repeated 1 time. Therefore it matches “aab”. |
“mississippi” | “mis*is*p*.” | False | - |
分析
题目的输入为:字符串
,匹配模式
输出为:匹配结果,True 或者 False
本题可以使用动态规划的方式进行求解。如果定义
为True时,表示
与
匹配上,则递推公式:
1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
2. P[i][j] = P[i][j - 2], if p[j - 1] == '*'
此时
重复0次;
3. P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.')
,如果p[j - 1] == '*'
且
至少重复一次;
解答
class Solution:
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
m, n = len(s), len(p)
dp = [[False]*(n+1) for i in range(m+1)]
dp[0][0] = True
for i in range(0, m+1):
for j in range(1, n+1):
if p[j-1] != '*':
dp[i][j] = i > 0 and dp[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '.')
else:
dp[i][j] = dp[i][j-2] or (i > 0 and dp[i-1][j] and (s[i-1] == p[j-2] or p[j-2] == '.'))
return dp[m][n]
此外本题也有另一种解法,即两个方向的匹配动态规划解法。