44. Wildcard Matching

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

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

Note:

  s could be empty and contains only lowercase letters a-z.
  p could be empty and contains only lowercase letters a-z, and characters like ? or *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
  • Recursive
public boolean isMatch(String s, String p) {
    if(p.length() == 0) return s.length() == 0;
    if(s.length() > 0 && (p.charAt(0) == '?' || p.charAt(0) == s.charAt(0))) {
        return isMatch(s.substring(1, s.length()), p.substring(1, p.length()));
    } else if(p.charAt(0) == '*') {
        return s.length() > 0 && isMatch(s.substring(1, s.length()), p) || isMatch(s, p.substring(1, p.length()));
    }
    return false;
}
  • Recursive With Memorisation
public boolean isMatch(String s, String p) {
    int[][] dp = new int[p.length()+1][s.length()+1];
    dp[0][0] = 1;
    return isMatchRecursive(s, p, dp);

}
public boolean isMatchRecursive(String s, String p, int[][] dp) {
    if(dp[p.length()][s.length()] != 0) return dp[p.length()][s.length()] == 1;
    if(p.length() == 0) return s.length() == 0;
    boolean result = false;
    if(s.length() > 0 && (p.charAt(0) == '?' || p.charAt(0) == s.charAt(0))) {
        result = isMatchRecursive(s.substring(1, s.length()), p.substring(1, p.length()), dp);
    } else if(p.charAt(0) == '*') {
        result = s.length() > 0 && isMatchRecursive(s.substring(1, s.length()), p, dp) || isMatchRecursive(s, p.substring(1, p.length()), dp);
    }
    dp[p.length()][s.length()] = result ? 1 : 2;
    return result;
}
  • DynamicProgramming

The same with Shortest Edit Distance

public boolean isMatch(String s, String p) {
    boolean[][] dp = new boolean[p.length()+1][s.length()+1];
    dp[0][0] = true;
    for(int i = 1; i <= p.length(); i++) {
        dp[i][0] = dp[i-1][0] && p.charAt(i-1) == '*';
        for(int j = 1; j <= s.length(); j++) {
            boolean addP = dp[i-1][j] && p.charAt(i-1) == '*';
            boolean addS = dp[i][j-1] && p.charAt(i-1) == '*';
            boolean addBoth = dp[i-1][j-1] && (p.charAt(i-1) == '*' || p.charAt(i-1) == '?' || p.charAt(i-1) == s.charAt(j-1));
            dp[i][j] = addP || addS || addBoth;
        }
    }
    return dp[p.length()][s.length()];
}