動機
很有趣的dp
Problem
Given an input string (s
) and a pattern (p
), implement wildcard pattern matching with support for '?'
and '*'
where:
'?'
Matches any single character.'*'
Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
Example 1:
Input: s = aa, p = aOutput: falseExplanation: a does not match the entire string aa.
Example 2:
Input: s = aa, p = *Output: trueExplanation: '*' matches any sequence.
Example 3:
Input: s = cb, p = ?aOutput: falseExplanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.
Example 4:
Input: s = adceb, p = *a*bOutput: trueExplanation: The first '*' matches the empty sequence, while the second '*' matches the substring dce.
Example 5:
Input: s = acdcb, p = a*c?bOutput: false
Constraints:
0 <= s.length, p.length <= 2000
s
contains only lowercase English letters.p
contains only lowercase English letters,'?'
or'*'
.
Sol
原本在i < 0
的case想說讓遞迴處理*
,但是這樣會讓後面的i都要重新檢查,同時會因為*
的case導致最後不論如何都會變成true或是loop
所以直接處理掉了
class Solution:
def isMatch(self, s: str, p: str) -> bool:
@cache
def dp(i,j):
if i < 0 and j < 0:
return True
elif j < 0:
return False
elif i < 0:
return all([c == '*' for c in p[:j+1]])
# return dp(i,j-1)
elif p[j] == '?':
return dp(i-1,j-1)
elif p[j] == '*':
# single, none
return dp(i-1,j) or dp(i,j-1)
else:
if s[i] == p[j]:
return dp(i-1,j-1)
else:
return False
return dp(len(s)-1,len(p)-1)