Tag Archives: LeetCode

Leet code 44 wildcard matching – wildcard matching – Java

Question original link https://leetcode.com/problems/wildcard-matching

The implementation supports’?’and’ * ‘wildcard pattern matching.

‘?’ matches any single character.

‘*’ matches any character sequence (including null).

You must match the entire input string (not just partial substrings).

Some examples:

isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

Dynamic programming is used. Set the input string as s, length as m, mode string as P, length as N, Boolean array DP [M + 1] [n + 1].

DP [0] [J + 1] indicates whether the empty string matches P [0.. J], and DP [i + 1] [J + 1] indicates whether s [0.. I] matches P [0.. J].

If P [J] = ‘*’, then DP [i + 1] [J + 1] = DP [i] [J + 1] | DP [i + 1] [J].

If P [J] = ‘?’ | P [J] = = s [i], then DP [i + 1] [J + 1] = DP [i] [J].

In other cases, DP [i + 1] [J + 1] = false.

public class Solution {
  public static boolean isMatch(String s, String p) {
    boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
    dp[0][0] = true;
    for (int j = 0; j < p.length(); j++) {
      if (dp[0][j] && p.charAt(j) == '*') {
        dp[0][j + 1] = true;
      }
    }
    for (int i = 0; i < s.length(); i++) {
      for (int j = 0; j < p.length(); j++) {
        if (p.charAt(j) == '*') {
          dp[i + 1][j + 1] = dp[i][j + 1] || dp[i + 1][j];
        } else if (p.charAt(j) == '?' || p.charAt(j) == s.charAt(i)) {
          dp[i + 1][j + 1] = dp[i][j];
        }
      }
    }
    return dp[s.length()][p.length()];
  }
}

[LeetCode] 291. Word Pattern II

Given apatternand a stringstr, find ifstrfollows the same pattern.

Herefollowmeans a full match, such that there is a bijection between a letter inpatternand anon-emptysubstring instr.

Examples:

pattern ="abab", str ="redblueredblue"should return true.

pattern ="aaaa", str ="asdasdasdasd"should return true.

pattern ="aabb", str ="xyzabcxzyabc"should return false.

Notes:
You may assume bothpatternandstrcontains only lowercase letters.

290. Word pattern is an extension of word pattern. The difference is that there are no spaces in the word string, so we can’t split the words directly by spaces.

You can use the backtracking method to judge each case, use the hash table to establish the mapping between pattern characters and words, and use the variables p and R to record the position of the current recursive pattern characters and word strings. In the recursive function, if P and R are equal to the length of the pattern string and single word string respectively, it means that the matching is completed successfully, and return to ture. Otherwise, if a If the match is reached and the other one is not, it means that the match failed and returns false.

Solution: backtracking

Python:

# Time:  O(n * C(n - 1, c - 1)), n is length of str, c is unique count of pattern,
#                                there are H(n - c, c - 1) = C(n - 1, c - 1) possible splits of string,
#                                and each one costs O(n) to check if it matches the word pattern.
# Space: O(n + c)

class Solution(object):
    def wordPatternMatch(self, pattern, str):
        """
        :type pattern: str
        :type str: str
        :rtype: bool
        """
        w2p, p2w = {}, {}
        return self.match(pattern, str, 0, 0, w2p, p2w)


    def match(self, pattern, str, i, j, w2p, p2w):
        is_match = False
        if i == len(pattern) and j == len(str):
            is_match = True
        elif i < len(pattern) and j < len(str):
            p = pattern[i]
            if p in p2w:
                w = p2w[p]
                if w == str[j:j+len(w)]:  # Match pattern.
                    is_match = self.match(pattern, str, i + 1, j + len(w), w2p, p2w)
                # Else return false.
            else:
                for k in xrange(j, len(str)):  # Try any possible word
                    w = str[j:k+1]
                    if w not in w2p:
                        # Build mapping. Space: O(n + c)
                        w2p[w], p2w[p] = p, w;
                        is_match = self.match(pattern, str, i + 1, k + 1, w2p, p2w)
                        w2p.pop(w), p2w.pop(p);
                    if is_match:
                        break
        return is_match  

C++:

class Solution {
public:
    bool wordPatternMatch(string pattern, string str) {
        unordered_map<char, string> m;
        return helper(pattern, 0, str, 0, m);
    }
    bool helper(string pattern, int p, string str, int r, unordered_map<char, string&> &m) {
        if (p == pattern.size() && r == str.size()) return true;
        if (p == pattern.size() || r == str.size()) return false;
        char c = pattern[p];
        for (int i = r; i < str.size(); ++i) {
            string t = str.substr(r, i - r + 1);
            if (m.count(c) && m[c] == t) {
                if (helper(pattern, p + 1, str, i + 1, m)) return true;
            } else if (!m.count(c)) {
                bool b = false;
                for (auto it : m) {
                    if (it.second == t) b = true;
                } 
                if (!b) {
                    m[c] = t;
                    if (helper(pattern, p + 1, str, i + 1, m)) return true;
                    m.erase(c);
                }
            }
        }
        return false;
    }
};  

C++:

class Solution {
public:
    bool wordPatternMatch(string pattern, string str) {
        unordered_map<char, string> m;
        set<string> s;
        return helper(pattern, 0, str, 0, m, s);
    }
    bool helper(string pattern, int p, string str, int r, unordered_map<char, string> &m, set<string&> &s) {
        if (p == pattern.size() && r == str.size()) return true;
        if (p == pattern.size() || r == str.size()) return false;
        char c = pattern[p];
        for (int i = r; i < str.size(); ++i) {
            string t = str.substr(r, i - r + 1);
            if (m.count(c) && m[c] == t) {
                if (helper(pattern, p + 1, str, i + 1, m, s)) return true;
            } else if (!m.count(c)) {
                if (s.count(t)) continue;
                m[c] = t;
                s.insert(t);
                if (helper(pattern, p + 1, str, i + 1, m, s)) return true;
                m.erase(c);
                s.erase(t);
            }
        }
        return false;
    }
};