10. Regular Expression Matching && 44. Wildcard Matching

 10. Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

 

class Solution {
  public boolean isMatch(String s, String p) {
    return isMatch(s, 0, p, 0);
  }

  private boolean isMatch(String s, int si, String p, int pi) {
    if (pi == p.length())
      return si == s.length();

    if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') //if followed by star
    {
      if (si == s.length())
        return isMatch(s, si, p, pi + 2);
      if (isMatch(s, si, p, pi + 2)) //if can skip current * pattern
        return true;
      if (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.')// cannot skip * pattern, must match
        return isMatch(s, si + 1, p, pi);
      return false;
      /*
      The code above is optimized from this TLE implementation.
      if(si == s.length())
          return isMatch(s, si, p, pi+2);
      if(s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.'){ //if s match p
          return isMatch(s, si+1, p, pi) ||  //case1: skip current char in s
                 isMatch(s, si, p, pi+2) ||  //case2: skip current two chars in p
                 isMatch(s, si+1, p, pi+2);  //case3: skip current char in s and current two chars in p
      }
      else
          return isMatch(s, si, p, pi+2);  //else must skip current two chars in p
       */
    } else {
      if (si == s.length())
        return false;
      if (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.')
        return isMatch(s, si + 1, p, pi + 1);
      return false;
    }
  }
}

 

44. Wildcard Matching

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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

Slightly modified the code for Regular Expression Matching, you will get a TLE solution.

class Solution {
  public boolean isMatch(String s, String p) {
    return isMatch(s, 0, p, 0);
  }

  private boolean isMatch(String s, int si, String p, int pi) {
    if (pi == p.length())
      return si == s.length();

    if (p.charAt(pi) == '*') {
      if (si == s.length())
        return isMatch(s, si, p, pi + 1);
      if (isMatch(s, si, p, pi + 1) || isMatch(s, si + 1, p, pi))
        return true;
      return false;
    } else {
      if (si == s.length())
        return false;
      if (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '?')
        return isMatch(s, si + 1, p, pi + 1);
      return false;
    }
  }
}

 

2D DP solution. O(MN) complexity and space.

DP[stringRow][patternCol] indicated whether s.substring(0,stringRow) can match p.substring(0,patternCol)

class Solution {
  public boolean isMatch(String s, String p) {
    int row = s.length(), col = p.length();
    boolean[][] dp = new boolean[row + 1][col + 1];
    dp[0][0] = true; //"" can match ""
    for (int r = 1; r <= row; r++) {
      dp[r][0] = false;   //string with length cannot match ""
    }

    for (int c = 1; c <= col; c++) {
      if (p.charAt(c - 1) == '*') {
        dp[0][c] = true;    //"" can match all stars until ...
      } else {
        break;              //until it sees a non-star
      }
    }

    for (int strR = 1; strR <= row; ++strR) {
      //for the string s.substring(0,strR), iterate through patterns
      char sCurrent = s.charAt(strR - 1);
      
      for (int patC = 1; patC <= col; ++patC) {
        char pCurrent = p.charAt(patC - 1);
        if (pCurrent != '*') {
          dp[strR][patC] = 
            //when previous string can match previous pattern
            dp[strR - 1][patC - 1] &&  
            //check whether the incremental part matches.
            (sCurrent == pCurrent || pCurrent == '?');
        } else {
          dp[strR][patC] = dp[strR - 1][patC] ||  //when previous string can match current pattern
            //when current string can match previous pattern then we don't need current *
            dp[strR][patC - 1]; 
        }
      }
    }
    return dp[row][col];
  }
}

 

Linear Solution:

http://yucoding.blogspot.com/2013/02/leetcode-question-123-wildcard-matching.html

si is current string pointer.

pi is current pattern pointer.

match is the pointer for string already matched.

starIndex points to last star.

class Solution {
  public boolean isMatch(String s, String p) {
    int si = 0, pi = 0, match = 0, starIdx = -1;
    while (si < s.length()) {
      // advancing both pointers
      if (pi < p.length() && (p.charAt(pi) == '?' || s.charAt(si) == p.charAt(pi))) {
        si++;
        pi++;
      }
      // * found, only advancing p pointer
      else if (pi < p.length() && p.charAt(pi) == '*') {
        starIdx = pi;
        match = si;
        pi++;
      }
      // last p pointer was *, advancing string pointer
      else if (starIdx != -1) {
        pi = starIdx + 1;
        match++;
        si = match;
      }
      //current p pointer is not star, last patter pointer was not *
      //characters do not match
      else return false;
    }

    //check for remaining characters in p
    while (pi < p.length() && p.charAt(pi) == '*')
      pi++;

    return pi == p.length();
  }
}

 

 

 

 

转载于:https://www.cnblogs.com/neweracoding/p/5617728.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值