[LeetCode]44. Wildcard Matching

思路一:参考

主要思想如下:

由于*匹配多少个字符是不一定的,于是首先假设*不匹配任何字符。

当后续匹配过程中出错,采用回溯的方法,假设*匹配0个字符、1个字符、2个字符……i个字符,然后继续匹配。

因此s需要有一个spos指针,记录当p中的*匹配i个字符后,s的重新开始位置。

p也需要一个starpos指针指向*的位置,当回溯过后重新开始时,从starpos的下一位开始。

这边我参考了其他人的代码

class Solution {
public:
    bool isMatch(string s, string p) 
    {
        int ppos=0;
        int spos=0;
        int star=-1;//记录p字符串中当前的'*'的下标
        int match;//记录p[ppos]=='*'时,spos的位置
        while(spos<s.size())
        {
           if(ppos<p.size()&&(s[spos]==p[ppos]||p[ppos]=='?'))//当前字符匹配
           {
               spos++;
               ppos++;
           }
           else if(ppos<p.size()&&p[ppos]=='*')//当前字符不匹配 当前p[ppos]=‘×’
           {
               match=spos;
               star=ppos++;
           }
           else if(star>=0)//当前字符不匹配 当前p[ppos]!=‘×’ 前一个模式串是'*'
           {
               ppos=star+1;
               spos=++match;
           }
           else
                return false;
        }
        while(ppos<p.size()&&p[ppos]=='*') ppos++;
        return ppos==p.size();
    }
};

方法二:递归

参考

这需要说明一下如何理解“*可以匹配任意多字符”:其实这可以分为两种情况,我们用“aa”和“*a*”举例说明:

  1. aa 和 *a 已经匹配,由于最后一个字符是*,所以整个字符串是匹配的,换言之,如果遇到一个*,只要星号之前的串是匹配的,整体就是匹配的。
  2. a 和 *a 匹配,让剩下的一个 a 和最后的 * 匹配。
于是可以得出基本思路:扫描匹配串,遇到*就考虑上边的两种情况,也就是dp[i - 1][j] 和 dp[i][j - 1];如果遇到?,就让问号匹配当前字符,这就转换成了s[i - 1] 和 p[j - 1]是否匹配的问题。
class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size(), n = p.size();
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
        //dp[0][0]可以理解为空串和空串匹配
        dp[0][0] = true;
        //dp[0][i]表示空串只能匹配到第一个*
        for (int i = 1; i <= n; ++i) {
            if (p[i - 1] == '*') {
                dp[0][i] = dp[0][i - 1];
            }
        }
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p[j - 1] == '*') {
                    //dp[i - 1][j]就是我们讨论的第一种情况
                    //dp[i][j - 1]是第二种情况
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                } else {
                    dp[i][j] = (s[i - 1] == p[j - 1] || p[j - 1] == '?') && dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
};