Wildcard Matching

Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'

Problem Statement

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:

1
2
3
Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

1
2
3
Input: s = "aa", p = "*"
Output: true
Explanation: '*' matches any sequence.

Example 3:

1
2
3
Input: s = "cb", p = "?a"
Output: false
Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.

Constraints:

  • 0 <= s.length, p.length <= 2000
  • s contains only lowercase English letters.
  • p contains only lowercase English letters, ‘?’ or ‘*’.

Test Cases

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
"aa"
"a"
"aa"
"*"
"cb"
"?a"
"aa"
"aaaaa"
"aa"
"aa*"
"adceb"
"*a*b"
"babaaababaabababbbbbbaabaabbabababbaababbaaabbbaaab"
"***bba**a*bbba**aab**b"

See the problem

Solution

Solution Recursive: Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        p_size = len(p)
        s_size = len(s)
        i=j=0
        while i<p_size:
            if j>=s_size:
                while (i<p_size and p[i]=="*"):
                    i+=1
                if i<p_size:
                    return False
                else:
                    return True
            elif (p[i]==s[j] or p[i]=='?'):
                i+=1
                j+=1
            elif (p[i]=="*"):
                return (
                    self.isMatch(s[j+1:], p[i+1:]) or
                    self.isMatch(s[j:], p[i+1:]) or
                    self.isMatch(s[j+1:], p[i:]))
            else:
                return False
        if j<s_size:
            return False
        else:
            return True

Solution Iterative: Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution:
    def get_value_at_index(self, arr, i, j):
        if i >= 0 and j >= 0:
            return arr[i % 2][j]
        elif i == -1 and j == -1:
            return True
        else:
            return False

    def isMatch(self, s: str, p: str) -> bool:
        p_size = len(p)
        s_size = len(s)
        first_el = True

        if not s_size:
            for i in range(p_size):
                if p[i] != "*":
                    return False
            return True
        if not p_size:
            return False

        mem = [[False] * s_size for i in range(2)]

        for i in range(p_size):
            for j in range(s_size):
                if p[i] == s[j] or p[i] == "?":
                    mem[i % 2][j] = first_el or self.get_value_at_index(
                        mem, i - 1, j - 1
                    )
                    first_el = False
                elif p[i] == "*":
                    mem[i % 2][j] = (
                        self.get_value_at_index(mem, i - 1, j - 1)
                        or self.get_value_at_index(mem, i, j - 1)
                        or self.get_value_at_index(mem, i - 1, j)
                    )
                else:
                    mem[i % 2][j] = False
                    first_el = False

        return mem[(p_size - 1) % 2][s_size - 1]