Wildcard matching [leetcode] direct match and DP

Source: Internet
Author: User

This is similar to the regular expression matching, but the data is relatively strong.

We also use dp (I, j) to indicate whether s [0... I-1] and P [0... J-1] Match

The basic situation is similar, but it is simpler:

1. DP (0, 0) = true

2. DP (0, j) = dp (0, J-1) & P [J-1] = '*'

3. DP (I, 0) = false

Generally, dp (I, j ):

1. DP (I-1, J-1) & (s [I-1] = P [J-1] | P [J-1] = '? ')

2. DP (I, J-1) & P [J-1] = '*'

3. DP (I-1, j) & P [J-1] = '*'

Since row I only uses the data of the row I-1, the space can be compressed to one dimension. We use a bool currow to indicate the row number of the current access ,! Currow indicates I-1 rows

First version

bool isMatch(const char *s, const char *p) {        int m = strlen(s);        int n = strlen(p);        bool curR = 0;        vector<vector<bool>> dp(2);        dp[curR] = (vector<bool>(n+1));        dp[!curR] = (vector<bool>(n+1));        dp[0][0] = true;        for (int i = 1; i <= n; i++)            dp[0][i] = (p[i-1] == '*' && dp[0][i-1]);                const char* tmp = p;          int cnt = 0;          while (*tmp != '\0') if (*(tmp++) != '*') cnt++;          if (cnt > m) return false;                  for (int i = 1; i <= m; i++)        {            curR = !curR;            dp[curR][0]=false;            for (int j = 1; j <= n; j++)            {                dp[curR][j] = (dp[!curR][j-1] && (s[i-1] == p[j-1] || p[j-1] == '?') ||                            dp[curR][j-1] && p[j-1] == '*' ||                            dp[!curR][j] && p[j-1] == '*');            }        }        return dp[curR][n];    }

Note that there is a pruning, if (CNT> m) return false, used to quickly exclude nonconformities. If there is no such paragraph, it will be TLE.

Version 2

bool isMatch(const char *s, const char *p) {        int m = strlen(s);        int n = strlen(p);        if (!quickElimination(s,p)) return false;        bool curR = 0;        vector<vector<bool>> dp(2);        dp[curR] = (vector<bool>(n+1));        dp[!curR] = (vector<bool>(n+1));        dp[0][0] = true;        for (int i = 1; i <= n; i++)            dp[0][i] = (p[i-1] == '*' && dp[0][i-1]);                for (int i = 1; i <= m; i++)        {            curR = !curR;            dp[curR][0]=false;            for (int j = 1; j <= n; j++)            {                if (p[j-1] == '*')                    dp[curR][j] = dp[curR][j-1] || dp[!curR][j];                else if (s[i-1] == p[j-1] || p[j-1] == '?')                    dp[curR][j] = dp[!curR][j-1];                else                    dp[curR][j] = false;            }        }        return dp[curR][n];    }        bool quickElimination(const char *s, const char *p)    {        int cnt = 0;          while (*p != '\0') if (*(p++) != '*') cnt++;          if (cnt > strlen(s)) return false;        return true;    }
The main difference is that when we compute dp (I, j), we use if-else to replace a series of logical operators, increasing the speed by about 30%. When the first version is used for computing, when a statement fails, it calculates the next condition connected with |, resulting in more operations.

Complexity: O (slen * Plen)


Direct Matching Method

In.

    bool isMatch(const char *s, const char *p) {        // Start typing your C/C++ solution below        // DO NOT write int main() function                 const char* star=NULL;        const char* ss=s;         while (*s){            if ((*p=='?')||(*p==*s)){s++;p++;continue;}            if (*p=='*'){star=p++; ss=s;continue;}            if (star){ p = star+1; s=++ss;continue;}            return false;        }        while (*p=='*'){p++;}        return !*p;    }
The main idea is:

1. * s = * P or * P =? : Match, s ++ P ++.
2. P = '*': it is also a match, but there may be 0 or more characters for matching. Therefore, save the location of '*' (STAR ), and save the location of S (SS ).
3. If it does not match, check whether '*' exists before '*'. If no value exists, false is returned. If yes, the next position of the SS is re-matched with the position after start.
The brute force law is complex with O (slen * slen ).


In this example, Plen and slen are not much different, And the brute force law can find unmatched strings during the search process to terminate the search. DP must traverse all sub-problems before providing solutions, so the second method is much faster.

On OJ, the violent law took 116 Ms, while DP took 720 Ms.

Wildcard matching [leetcode] direct match and DP

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.