Wildcard Matching

Question

  1. Implement wildcard pattern matching with support for '?' and '*'.
  2. '?' Matches any single character.
  3. '*' Matches any sequence of characters (including the empty sequence).
  4. The matching should cover the entire input string (not partial).
  5. Example
  6. isMatch("aa","a") false
  7. isMatch("aa","aa") true
  8. isMatch("aaa","aa") false
  9. isMatch("aa", "*") true
  10. isMatch("aa", "a*") true
  11. isMatch("ab", "?*") true
  12. isMatch("aab", "c*a*b") false

题解1 - DFS

字符串的通配实现。’?‘表示匹配单一字符,’*‘可匹配任意多字符串(包含零个)。要匹配的字符串设为s, 模式匹配用的字符串设为p,那么如果是普通字符,两个字符串索引向前推进一位即可,如果p中的字符是?也好办,同上处理,向前推进一位。所以现在的关键就在于如何处理’*‘, 因为*可匹配0, 1, 2…个字符,所以遇到*时,s应该尽可能的向前推进,注意到p*后面可能跟有其他普通字符,故s向前推进多少位直接与p*后面的字符相关。同时此时两个字符串的索引处即成为回溯点,如果后面的字符串匹配不成功,则s中的索引向前推进,向前推进的字符串即表示和p*匹配的字符个数。

Java

  1. public class Solution {
  2. /**
  3. * @param s: A string
  4. * @param p: A string includes "?" and "*"
  5. * @return: A boolean
  6. */
  7. public boolean isMatch(String s, String p) {
  8. if (s == null || p == null) return false;
  9. if (s.length() == 0|| p.length() == 0) return false;
  10. return helper(s, 0, p, 0);
  11. }
  12. private boolean helper(String s, int si, String p, int pj) {
  13. // index out of range check
  14. if (si == s.length() || pj == p.length()) {
  15. if (si == s.length() && pj == p.length()) {
  16. return true;
  17. } else {
  18. return false;
  19. }
  20. }
  21. if (p.charAt(pj) == '*') {
  22. // remove coninuous *
  23. while (p.charAt(pj) == '*') {
  24. pj++;
  25. // index out of range check
  26. if (pj == p.length()) return true;
  27. }
  28. // compare remaining part of p after * with s
  29. while (si < s.length() && !helper(s, si, p, pj)) {
  30. si++;
  31. }
  32. // substring of p equals to s
  33. return si != s.length();
  34. } else if (s.charAt(si) == p.charAt(pj) || p.charAt(pj) == '?') {
  35. return helper(s, si + 1, p, pj + 1);
  36. } else {
  37. return false;
  38. }
  39. }
  40. }

源码分析

其中对*的处理和递归回溯是这段代码的精华。

复杂度分析

最坏情况下需要不断回溯,时间复杂度 O(n!) \times O(m!), 空间复杂度 O(1)(不含栈空间)。

题解2

C++

  1. bool isMatch(string s, string p) {
  2. int star = 0, ss = 0, i = 0, j = 0;
  3. while (s[i]) {
  4. if (p[j] == '?' || p[j] == s[i]) {j++; i++; continue;}
  5. if (p[j] == '*') {star = ++j; ss = i; continue;}
  6. if (star) {j = star; i = ++ss; continue;}
  7. return false;
  8. }
  9. while (p[j] == '*') j++;
  10. return !p[j];
  11. }

Reference