![]() |
VOOZH | about |
Given two strings pat and txt which may be of different lengths. Check if the wildcard pattern(pat) matches with txt or not.
The wildcard pattern pat can include the characters '?' and '*'.
Note: After processing, the wildcard pattern pat must completely match the entire text txt.
Input: txt = "abcde", pat = "a?c*"
Output: true
Explanation: ? matches the character b in the text and * matches the substring de in the text.Input: txt = "baaabab", pat = "a*ab"
Output: false
Explanation: The pattern starts with a, but the text starts with b, so the pattern does not match the text.Input: txt = "abc", pat = "*"
Output: true
Explanation: The pattern * matches to the entire string "abc".
Table of Content
The idea is to recursively check if the given pattern can match the text by comparing characters from the end of both strings.
If both strings become empty at the same time, it means the match is successful. If the text becomes empty but the pattern still has characters, it can only match if all remaining pattern characters are *.
When the current characters are the same, or the pattern has a ?, we move one step back in both strings. If the current character in the pattern is *, it can either match no character (skip *) or one or more characters (move left in the text and keep *).
By exploring these possibilities recursively, we can determine whether the entire pattern matches the text.
true
We can observe that while matching a pattern with wildcards, many overlapping subproblems naturally occur.
For instance, when checking if pattern[0..i] matches text[0..j], we might again need to evaluate smaller cases like pattern[0..i-1] with text[0..j] or pattern[0..i] with text[0..j-1], especially when '*' can represent zero or more characters.To handle this efficiently, we use memoization a technique that stores the result of each state (i, j), representing whether the prefixes up to i and j match.
If the same state is encountered again, we simply reuse the stored result instead of recomputing it, thus avoiding redundant calculations and improving efficiency.
true
The idea is to convert the recursive relation into a bottom-up table form.
We create a 2D DP table dp[i][j], where each cell represents whether the first i characters of the pattern match the first j characters of the text.
The base case is that an empty pattern matches an empty text, so dp[0][0] = true.
If the pattern begins with *, it can match an empty string, so we propagate that condition along the first column.
Then, we fill the table iteratively:
- When the current pattern character matches the current text character or is a ?, we take the diagonal value dp[i-1][j-1].
- When it is *, we can either ignore it (take dp[i-1][j]) or let it match one more character (take dp[i][j-1]).
By the end, dp[n][m] gives the final answer whether the entire pattern matches the text.
true
In the above approach, we can optimize further by observing that dp[i][j] depends only on the previous row (i-1) and the current row.
This means we donβt need to store the entire 2D DP table.
We use two 1D arrays β one (prev) for the previous row and another (curr) for the current row. For each character in the pattern and text, we fill curr[j] using values from prev and already computed entries in curr.
The base cases handle situations like matching an empty text or patterns that consist only of *.After completing one row, we assign prev = curr and move on to the next pattern character. Finally, the result for the entire match is available in prev[m].
true
In this approach, we match the text and pattern using two pointers, handling * and ? without extra space. The * can represent any sequence of characters, while ? matches exactly one. When we encounter a *, we record its position in the pattern and the corresponding position in the text. If a mismatch occurs later, we backtrack by returning to the last * β we move the pattern pointer to just after * and advance the text pointer by one from the last recorded match position. This effectively treats the * as matching one more character in the text, allowing us to explore all valid possibilities efficiently.
true