44.wildcard-matching

      这道题也是正则表达式类的题目,和10题有很大程度的相似度,个人感觉难度上来讲,这道题要简单一点,有一点需要注意的是这道题不能用递归来解决,看到有个测试用例会超时,但也可能是我自己的思路上有缺陷,如果有大神,肯请指点。

      这道题是*号表示任何字符串包括空串:"",?表示可以与任意一个字符串匹配,所以,最特殊的还是*号,我们分情况讨论,

1、假设当前p[i] = s[j] 或者 p[i] == '?',则所以同时加一。

2、假设当前p[i] == '*',则,记录当前位置的下一个位置点。s的索引值不动,主要是为了涵盖*号代表空串的情况。p的索引值+1。

3、假设当前失配,即以上两种情况都不是,则寻找上一个*号记录点,将p串的索引和s串的索引都重新放在上一个索引点处的下一个位置,让*号代表长的字串,寻找可能的匹配情况。

4、如果发生失配的情况下依然未能找到有*号记录,则说明无法完成字串匹配,返回false。

以下是AC代码:

class Solution {
public:
    bool isMatch(string s, string p) {
        int pindex = 0, sindex = 0, sstart = 0, pstart = 0;
        while (sindex < s.size()) {
            if (p[pindex] == s[sindex] || p[pindex] == '?') {
                ++pindex;
                ++sindex;
            } else if (p[pindex] == '*') {
                pstart = ++pindex;
                sstart = sindex;
            } else if (pstart) {
                pindex = pstart;
                sindex = ++sstart;
            } else {
                return 0;
            }
        }
        while (pindex<p.size() && p[pindex]=='*') {
            ++pindex;
        }
        return pindex==p.size();
    }
};

这道题要说一点的是,递归程序之所以会出现超时问题,重要的原因在于一旦出现连续的*号,就会让复杂度增加很多。其实在本题目中,连续的*号在某种意义上是等价存在的。其实只需要记录最新的一个即可。如果要使用递归,可以尝试先处理一下多个连续*号,然后在进行递归操作。

以下是递归代码,会发生超时,但思想和10题完全一样:

class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.empty()) return s.empty();

        if (p[0] == '*') {
            return (isMatch(s, p.substr(1)) || (!s.empty() && isMatch(s.substr(1), p)));
        } else {
            return (!s.empty() && (s[0]==p[0]||p[0]=='?') && isMatch(s.substr(1), p.substr(1)));
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_29592167/article/details/83114404