Skip to content

Latest commit

 

History

History
165 lines (105 loc) · 3.38 KB

0044._wildcard_matching.md

File metadata and controls

165 lines (105 loc) · 3.38 KB

44. Wildcard Matching

难度: 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)