难度: Hard
原题连接
内容描述
Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "*"
Output: true
Explanation: '*' matches any sequence.
Example 3:
Input:
s = "cb"
p = "?a"
Output: false
Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.
Example 4:
Input:
s = "adceb"
p = "*a*b"
Output: true
Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".
Example 5:
Input:
s = "acdcb"
p = "a*c?b"
Output: false
思路 1 - 时间复杂度: O(len(s) * len(p))- 空间复杂度: O(len(s) * len(p))******
dp, 看完下面的代码就知道思路了
beats 61.92%
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
t = [[False] * (len(s) + 1) for i in range(len(p) + 1)]
t[0][0] = True
for i in range(1, len(p) + 1):
t[i][0] = t[i-1][0] and p[i-1] == '*'
for i in range(1, len(p)+1):
for j in range(1, len(s) + 1):
if p[i-1] != '*':
t[i][j] = (p[i-1] == s[j-1] or p[i-1] == '?') and t[i-1][j-1]
else:
t[i][j] = t[i][j-1] or t[i-1][j]
return t[-1][-1]
思路 2 - 时间复杂度: O(len(s) * len(p))- 空间复杂度: O(1)******
双指针
Worst case Should be O(NM)
think that s ="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" to match p ="*aaaaaab"( '*' in the beginning)
It's easy to see 'match' is moving step by step to almost the end, each time we move 'match', we will go through the whole tail of p (after '*') until we found out 'b' is not a match. Thus it's O(NM)
beats 94.80%
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
ps, pp, match, star_idx = 0, 0, 0, -1
while ps < len(s):
if pp < len(p) and (p[pp] == '?' or s[ps] == p[pp]): # advancing both pointers
ps += 1
pp += 1
elif pp < len(p) and p[pp] == '*': # found '*', only advancing pattern pointer
star_idx = pp
match = ps
pp += 1
elif star_idx != -1: # last pattern pointer was *, advancing string pointer
pp = star_idx + 1
match += 1
ps = match
else: # current pattern pointer is not star, last patter pointer was not *, characters do not match
return False
while pp < len(p) and p[pp] == '*': # check for remaining characters in pattern
pp += 1
return pp == len(p)