Thursday, January 22, 2015

Wildcard Matching (LeetCode Backtracking)

Question: 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).
The function prototype should be:
bool isMatch(const char *s, const char *p)
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

Idea: Backtracking. Use two pointers i, j to scan the two strings s, p respectively. If matches or s[i]=='?', push both pointers forward one step. If p[i]=='*', since '*' can match any number of letters, we first pretend this '*' never appears and try to match the next (as if '*' matches with 0 characters), if mismatch happens, go back to the '*' position to use the star to match the unmatched characters. If j reaches the end of p, but i has not, that means no mach. The same for the case when i reaches the end but j does not even if skip all the tailing '*'s.

Time: O(n) Space: O(1)

Code:
 public class Solution {  
   public boolean isMatch(String s, String p) {  
     int i=0,j=0;  
     int star=-1;  
     int si=i;  
     while(i<s.length())  
     {  
       if(j<p.length())  
       {  
         if((p.charAt(j)=='?'||p.charAt(j)==s.charAt(i)))  
         {  
           i++;  
           j++;  
           continue;  
         }  
         if(p.charAt(j)=='*')  
         {  
           star=j++;  
           si=i;  
           continue;  
         }  
       }  
       if(star!=-1)  
       {  
         j=star+1;  
         i=++si;  
         continue;  
       }  
       return false;  
     }  
     while(j<p.length()&&p.charAt(j)=='*')  
       j+=1;  
     return j==p.length();  
   }  
 }  

No comments:

Post a Comment