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).
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Similar Problems
Leetcode 44 Vs Leetcode 10 OR Regular Expression Matching
This problem look very similar to Leetcode 10. But actually it is slightly different.
Examples for Leetcode 10
|
|
Similar Examples for Leetcode 44 Aka Current Problem
|
|
Solution
Method 1 - Recursion
We have following cases in recursion:
- Base Case:
- If we’ve reached the end of the pattern
p
(j == p.length()
), the strings
must also be fully matched (i == s.length()
).
- If we’ve reached the end of the pattern
- Recursive Case:
- If the current character in the pattern is
'*'
, it can match zero or more characters froms
:isMatchHelper(s, p, i, j + 1)
: Considers'*'
as matching zero characters.isMatchHelper(s, p, i + 1, j)
: Considers'*'
as matching one or more characters.
- If the current character in the pattern is
'?'
or matches the current character ins
:- Move to the next character in both
s
andp
.
- Move to the next character in both
- If the current character in the pattern is
Code
|
|
Complexity
-
⏰ Time complexity:
O(2 ^ (m + n))
, wherem
is length of s andn
is length ofp
- Worst-Case Scenario can be that every character in the pattern is
*
. This results in two recursive calls for each character in the pattern, leading to exponential growth. - The total depth of the recursion tree can be up to the sum of the lengths of
s
andp
because each step potentially moves forward either ins
,p
, or both.
- Worst-Case Scenario can be that every character in the pattern is
-
🧺 Space complexity:
O(m + n)
, for using the recursion stack
Method 2 - Top Down DP with memoization
We can use a map to store results of subproblems, avoiding redundant computations with memoization, indexed by the string "i,j"
where i
is the current index in s
and j
is the current index in p
.
Code
|
|
Complexity
- ⏰ Time complexity:
O(m*n)
- 🧺 Space complexity:
O(m*n)
- for using memoization map -
O(m*n)
, - for using recursion stack -
O(m + n)
- for using memoization map -
Method 3 - Bottom up DP
We can change the code to use bottom up DP. Here are the steps:
- Initialization:
- Create a 2D boolean array
dp
with dimensions(m + 1) x (n + 1)
wherem
is the length of the input strings
andn
is the length of the patternp
. dp[i][j]
represents if the firsti
characters ofs
match the firstj
characters ofp
.
- Create a 2D boolean array
- Base Case:
dp[0][0]
istrue
because an empty string matches an empty pattern.- Handle the cases where the pattern starts with
*
, which can match an empty sequence.
- DP Table Filling:
- Iterate over each character of
s
andp
. - For each
*
in the pattern:dp[i][j]
becomestrue
if either:- The
*
matches zero characters (i.e., the previous statedp[i][j - 1]
). - The
*
matches one or more characters (i.e., the previous statedp[i - 1][j]
).
- The
- For each
?
or exact character match:dp[i][j]
is set based ondp[i - 1][j - 1]
.
- Iterate over each character of
- Result:
- The final result is stored in
dp[m][n]
, indicating whether the entire input strings
matches the patternp
.
- The final result is stored in
Code
|
|
Complexity
- ⏰ Time complexity:
O(m*n)
- 🧺 Space complexity:
O(m*n)