[
dp
string
]
Leetcode 0044. Wildcard Matching
Problem statement
https://leetcode.com/problems/wildcard-matching/
Solution
Another classical DP problem, similar to problem 0010. Let us define by dp(i, j) answer to the question if s[:i+1] and p[:j+1] can be matched. Then we can have different cases:
- if
i == -1 and j == -1it means, that we reached both empty strings, we returnTrue. - if
i == -1, it means, thatsstring is empty (andtis not empty), in this case we are happy only if all symbols ofpare equal to*, so we check last symbol checkdp(i, j-1). - if
j == -1, butiis not equal to-1, we already checked it previously, we returnFalse. - if
s[i] == p[j], that is last symbols are equal, we remove them and go todp(i-1, j-1) - if
p[j]not equal to?or*(that is it is letter) and it is not equal tos[i], we can not match, so we returnFalse. - if
p[j]is equal to?, we can match in only one way and we again go todp(i-1, j-1). - finally, if we have
*asp[j], we can have two options: we either say that this*is finished already, so we delete it, or not finished yet, then we delete symbol froms.
Complexity
Complexity: time and space complexity is O(mn).
Code
class Solution:
def isMatch(self, s, p):
@lru_cache(None)
def dp(i, j):
if i == -1 and j == -1: return True
if i == -1: return dp(i, j-1) and p[j] == "*"
if j == -1: return False
if s[i] == p[j]: return dp(i-1, j-1)
if s[i] != p[j] and p[j] not in "?*": return False
if p[j] == "?": return dp(i-1, j-1)
if p[j] == "*": return dp(i-1, j) or dp(i, j-1)
return dp(len(s) - 1, len(p) - 1)