LeetCode 0044. Wildcard Matching Solution in Java, Python, C++, JavaScript, Go & Rust | Explanation + Code

CoderIndeed
0
0044. Wildcard Matching

Description

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 = "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'.

 

Constraints:

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

Solutions

Solution 1: Memoization Search

We design a function dfs(i, j), which represents whether the string s starting from the i-th character matches the string p starting from the j-th character. The answer is dfs(0, 0).

The execution process of the function dfs(i, j) is as follows:

  • If i ≥ len(s), then dfs(i, j) is true only when j ≥ len(p) or p[j] = '*' and dfs(i, j + 1) is true.
  • If j ≥ len(p), then dfs(i, j) is false.
  • If p[j] = '*', then dfs(i, j) is true if and only if dfs(i + 1, j) or dfs(i + 1, j + 1) or dfs(i, j + 1) is true.
  • Otherwise, dfs(i, j) is true if and only if p[j] = '?' or s[i] = p[j] and dfs(i + 1, j + 1) is true.

To avoid repeated calculations, we use the method of memoization search and store the result of dfs(i, j) in a hash table.

The time complexity is O(m × n), and the space complexity is O(m × n). Where m and n are the lengths of the strings s and p, respectively.

PythonJavaC++GoTypeScriptC#
class Solution: def isMatch(self, s: str, p: str) -> bool: @cache def dfs(i: int, j: int) -> bool: if i >= len(s): return j >= len(p) or (p[j] == "*" and dfs(i, j + 1)) if j >= len(p): return False if p[j] == "*": return dfs(i + 1, j) or dfs(i + 1, j + 1) or dfs(i, j + 1) return (p[j] == "?" or s[i] == p[j]) and dfs(i + 1, j + 1) return dfs(0, 0)(code-box)

Solution 2: Dynamic Programming

We can convert the memoization search in Solution 1 into dynamic programming.

Define f[i][j] to represent whether the first i characters of string s match the first j characters of string p. Initially, f[0][0] = true, indicating that two empty strings are matching. For j ∈ [1, n], if p[j-1] = '*', then f[0][j] = f[0][j-1].

Next, we consider the case of i ∈ [1, m] and j ∈ [1, n]:

  • If p[j-1] = '*', then f[i][j] = f[i-1][j] \lor f[i][j-1] \lor f[i-1][j-1].
  • Otherwise, f[i][j] = (p[j-1] = '?' \lor s[i-1] = p[j-1]) \land f[i-1][j-1].

The final answer is f[m][n].

The time complexity is O(m × n), and the space complexity is O(m × n). Where m and n are the lengths of the strings s and p, respectively.

PythonJavaC++GoTypeScriptPHP
class Solution: def isMatch(self, s: str, p: str) -> bool: m, n = len(s), len(p) f = [[False] * (n + 1) for _ in range(m + 1)] f[0][0] = True for j in range(1, n + 1): if p[j - 1] == "*": f[0][j] = f[0][j - 1] for i in range(1, m + 1): for j in range(1, n + 1): if p[j - 1] == "*": f[i][j] = f[i - 1][j] or f[i][j - 1] or f[i - 1][j - 1] else: f[i][j] = f[i - 1][j - 1] and ( p[j - 1] == "?" or s[i - 1] == p[j - 1] ) return f[m][n](code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !