HomeLeetcode44. Wildcard Matching - Leetcode Solutions

44. Wildcard Matching – Leetcode Solutions

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).

Examples:

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

Solution in Python:

To solve the wildcard pattern matching problem where the pattern can include ? and *, we can use dynamic programming.

Python
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        # Initialize the DP table with False
        dp = [[False] * (len(p) + 1) for _ in range(len(s) + 1)]
        
        # Base case: empty pattern matches empty string
        dp[0][0] = True
        
        # Handle patterns like *, **, ***, etc.
        for j in range(1, len(p) + 1):
            if p[j - 1] == '*':
                dp[0][j] = dp[0][j - 1]
        
        # Fill the DP table
        for i in range(1, len(s) + 1):
            for j in range(1, len(p) + 1):
                if p[j - 1] == s[i - 1] or p[j - 1] == '?':
                    # If characters match or pattern character is '?'
                    dp[i][j] = dp[i - 1][j - 1]
                elif p[j - 1] == '*':
                    # If pattern character is '*', it can match any sequence
                    dp[i][j] = dp[i - 1][j] or dp[i][j - 1]
        
        return dp[len(s)][len(p)]

Detailed Explanation:

  1. Initialization:
    • We use a 2D list dp where dp[i][j] will be True if the first i characters in the string s match the first j characters of the pattern p.
    • The size of dp is (len(s) + 1) x (len(p) + 1) because we need to account for the empty string and empty pattern.
  2. Base Case:
    • dp[0][0] is True because an empty pattern matches an empty string.
    • We also handle the case where the pattern starts with one or more *. Each * can match the empty sequence, so we propagate True from left to right in the first row of the DP table.
  3. Filling the DP Table:
    • We iterate through each character of the string s and the pattern p.
    • If the characters match (s[i - 1] == p[j - 1]) or if the pattern has a ?, we set dp[i][j] = dp[i - 1][j - 1].
    • If the pattern has a *, it can either match zero characters (dp[i][j - 1]) or match one or more characters (dp[i - 1][j]).
  4. Final Result:
    • The final result is in dp[len(s)][len(p)], which indicates whether the entire string matches the entire pattern.

This approach ensures that we efficiently handle the wildcard pattern matching problem within the constraints given.

Solution in Javascript:

JavaScript
/**
 * @param {string} s
 * @param {string} p
 * @return {boolean}
 */
var isMatch = function(s, p) {
    // Initialize the DP table with false
    let dp = Array.from({ length: s.length + 1 }, () => Array(p.length + 1).fill(false));
    
    // Base case: empty pattern matches empty string
    dp[0][0] = true;
    
    // Handle patterns like *, **, ***, etc.
    for (let j = 1; j <= p.length; j++) {
        if (p[j - 1] === '*') {
            dp[0][j] = dp[0][j - 1];
        }
    }
    
    // Fill the DP table
    for (let i = 1; i <= s.length; i++) {
        for (let j = 1; j <= p.length; j++) {
            if (p[j - 1] === s[i - 1] || p[j - 1] === '?') {
                // If characters match or pattern character is '?'
                dp[i][j] = dp[i - 1][j - 1];
            } else if (p[j - 1] === '*') {
                // If pattern character is '*', it can match any sequence
                dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
            }
        }
    }
    
    return dp[s.length][p.length];
};

Solution in Java:

Java
class Solution {
    public boolean isMatch(String s, String p) {
        // Initialize the DP table with false
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        
        // Base case: empty pattern matches empty string
        dp[0][0] = true;
        
        // Handle patterns like *, **, ***, etc.
        for (int j = 1; j <= p.length(); j++) {
            if (p.charAt(j - 1) == '*') {
                dp[0][j] = dp[0][j - 1];
            }
        }
        
        // Fill the DP table
        for (int i = 1; i <= s.length(); i++) {
            for (int j = 1; j <= p.length(); j++) {
                if (p.charAt(j - 1) == s.charAt(i - 1) || p.charAt(j - 1) == '?') {
                    // If characters match or pattern character is '?'
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (p.charAt(j - 1) == '*') {
                    // If pattern character is '*', it can match any sequence
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                }
            }
        }
        
        return dp[s.length()][p.length()];
    }

    
}

Solution in C#:

C#
public class Solution {
    public bool IsMatch(string s, string p) {
        // Initialize the DP table with false
        bool[,] dp = new bool[s.Length + 1, p.Length + 1];
        
        // Base case: empty pattern matches empty string
        dp[0, 0] = true;
        
        // Handle patterns like *, **, ***, etc.
        for (int j = 1; j <= p.Length; j++) {
            if (p[j - 1] == '*') {
                dp[0, j] = dp[0, j - 1];
            }
        }
        
        // Fill the DP table
        for (int i = 1; i <= s.Length; i++) {
            for (int j = 1; j <= p.Length; j++) {
                if (p[j - 1] == s[i - 1] || p[j - 1] == '?') {
                    // If characters match or pattern character is '?'
                    dp[i, j] = dp[i - 1, j - 1];
                } else if (p[j - 1] == '*') {
                    // If pattern character is '*', it can match any sequence
                    dp[i, j] = dp[i - 1, j] || dp[i, j - 1];
                }
            }
        }
        
        return dp[s.Length, p.Length];
    }

    
}

Subscribe
Notify of

0 Comments
Inline Feedbacks
View all comments

Popular