0010: Regular Expression Matching
Problem Statement
Given an input string s
and a pattern p
, implement regular expression matching with support for '.'
and '*'
where:
'.'
Matches any single character.'*'
Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Example 1:
Input: s = "aa", p = "a" Output: false Explanation: "a" does not match the entire string "aa".
Example 2:
Input: s = "aa", p = "a*" Output: true Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input: s = "ab", p = ".*" Output: true Explanation: ".*" means "zero or more (*) of any character (.)".
Constraints:
1 <= s.length <= 20
1 <= p.length <= 20
s
contains only lowercase English letters.p
contains only lowercase English letters,'.'
, and'*'
.- It is guaranteed for each appearance of the character
'*'
, there will be a previous valid character to match.
Code Solution
class Solution:
def isMatch(self, s: str, p: str) -> bool:
@cache
def rec(sx, px):
# if pattern ends, string must end too
if px >= len(p):
return sx == len(s)
# check if prefix `can_match`:
can_match = sx < len(s) and p[px] in {s[sx], '.'}
# ---------------------------------
# next_char == '*':
# return `take_it` or `skip_it`
# ---------------------------------
if px < len(p) - 1 and p[px + 1] == '*':
take_it = can_match and rec(sx + 1, px)
skip_it = rec(sx, px + 2)
return take_it or skip_it
# ----------------
# next_char != '*'
# ----------------
else:
return can_match and rec(sx + 1, px + 1)
return False
return rec(0, 0)