Thursday, January 8, 2015

LeetCode 44: Wildcard Matching

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
public class Solution {
    public boolean isMatch(String s, String p) {
        // DP can't handle this question because of high time complexity.
        // Here we adopt greedy algorithm.
        // If matched, continue consider next character of 's'.
        // If not matched, find if there is '*' before current character of 'p'.
        // If found '*', re-consider if the next element of '*' of 'p' match (mark+1)th element of 's'.
        int m = s.length();
        int n = p.length();
        
        int i = 0;  
        int j = 0;
        int mark = -1; // Mark character of 's' when encounter '*'.
        int star = -1; // Store index of last '*'.
        
        while (i < m)
        {
            // If matched, continue consider next character of 's'.
            if (j<n && (s.charAt(i)==p.charAt(j) || p.charAt(j)=='?'))
            {
                i++;
                j++;
            }
            // Mark '*' and continue using next character of 'p' to match current character of 's'.
            else if (j<n && p.charAt(j) == '*')
            {
                mark = i;
                star = j++;
            }
            // It represents there is '*' before current character of 'p'
            else if (star != -1)
            {
                i = ++mark; // Next try will skip current mark (In other words, use '*' cover current 'mark').
                j = star+1;
            }
            // Not matched
            else
                return false;
        }
        
        // When 's' has been reached end, there are still some characters of 'p' unchecked.
        // They must be '*' if 'p' match 's'.
        while (j<n && p.charAt(j)=='*')
            j++;
        
        // If don't find any unmatched character until 's' and 'p' both reach end, return true.    
        return j == n;  
    }
}

No comments:

Post a Comment