LeetCode 44. Wildcard Matching

1. 题目描述

‘?’ 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

2. 解题思路

这实际上是一个非常典型的dp问题, 下面给出 转移方程:

f[i,j]=f[i1,j1]f[i1,j]||f[i,j1]falsep[i1]==s[j1]||p[i1]==?p[i1]==else

我们现在写的这个解法的空间复杂度 是 O(n2) 其实, 可以利用滚动数组改善为 O(n)

3. code

class Solution {
public:
    bool isMatch(string s, string p) {
        int len_s = s.size();
        int len_p = p.size();
        vector<vector<bool>> arr(len_p + 1, vector<bool>(len_s + 1, false));
        arr[0][0] = true;

        for (int i = 1; i != len_p + 1; i++){
            for (int j = 0; j != len_s + 1; j++){
                if (j == 0){
                    if (p[i - 1] == '*')
                        arr[i][j] = arr[i - 1][j];
                }
                else{
                    if (p[i - 1] == s[j - 1] || p[i - 1] == '?')
                        arr[i][j] = arr[i - 1][j - 1];                      
                    else if (p[i - 1] == '*'){
                        arr[i][j] = arr[i - 1][j] || arr[i][j - 1];
                    }
                    else
                        arr[i][j] = false;
                }
            }
        }

        return arr[len_p][len_s];
    }
};

4. 大神解法

这个算法时间复杂度 为 O(n) , 这个算法蛮巧妙的, 不过个人还是比较能接受dp一些

/* I found this solution from http://yucoding.blogspot.com/2013/02/leetcode-question-123-wildcard-matching.html The basic idea is to have one pointer for the string and one pointer for the pattern. This algorithm iterates at most length(string) + length(pattern) times, for each iteration, at least one pointer advance one step. Here is Yu's elegant solution in C++ */
 bool isMatch(const char *s, const char *p) {
        const char* star=NULL;
        const char* ss=s;
        while (*s){
            //advancing both pointers when (both characters match) or ('?' found in pattern)
            //note that *p will not advance beyond its length 
            if ((*p=='?')||(*p==*s)){s++;p++;continue;} 

            // * found in pattern, track index of *, only advancing pattern pointer 
            if (*p=='*'){star=p++; ss=s;continue;} 

            //current characters didn't match, last pattern pointer was *, current pattern pointer is not *
            //only advancing pattern pointer
            if (star){ p = star+1; s=++ss;continue;} 

           //current pattern pointer is not star, last patter pointer was not *
           //characters do not match
            return false;
        }

       //check for remaining characters in pattern
        while (*p=='*'){p++;}

        return !*p;  
    }

你可能感兴趣的:(LeetCode)