44. Wildcard Matching

在这里插入图片描述

又是一道通配符的问题,和:https://blog.csdn.net/weixin_43462819/article/details/100878953 很像,但是有一个关键的思路还是没能够灵活运用,导致没有做出最优的解法。

首先是自己的解法:

class Solution {
public:
    bool isMatch(string s, string p) {
        int ssz = s.size(), psz = p.size();
        vector<vector<bool>> dp(ssz+1, vector<bool>(psz+1, false));
        dp[0][0] = true;
        for (int j = 1; j <= psz; ++j)
            if (p[j-1] == '*' && dp[0][j-1])
                dp[0][j] = true;
        
        for (int i = 1; i <= ssz; ++i)
            for (int j = 1; j <= psz; ++j) {
                if (p[j-1] != '*' && p[j-1] != '?')
                    dp[i][j] = (s[i-1] == p[j-1] && dp[i-1][j-1]);
                else if (p[j-1] == '?')
                    dp[i][j] = dp[i-1][j-1];
                else {
                    for (int k = i; k >= 0; --k)
                        if (dp[k][j-1]) {
                            dp[i][j] = true;
                            break;
                        }
                }
            }
        
        return dp.back().back();
    }
};

其中那个内部的循环的意思是:按照’*'为空,有一个,有两个。。。这样全部检查一遍,这样最终做出来的时间很长。

然后是一个关键的思路:
如果 ‘ * ’ 为空,则为dp[i][j-1],容易理解
如果‘ * ’不为空,至少有一个的话,就看dp[i-1][j],这个不太容易理解,原因是:
看dp[i-1][j],对于在j位置上的’*’,它可以为空,为一个,为两个。。。,那么对应到dp[i][j],那就是为一个,为两个。。。

class Solution {
public:
    bool isMatch(string s, string p) {
        int ssz = s.size(), psz = p.size();
        vector<vector<bool>> dp(ssz+1, vector<bool>(psz+1, false));
        dp[0][0] = true;
        for (int j = 1; j <= psz; ++j)
            if (p[j-1] == '*' && dp[0][j-1])
                dp[0][j] = true;
        
        for (int i = 1; i <= ssz; ++i)
            for (int j = 1; j <= psz; ++j) {
                if (p[j-1] != '*' && p[j-1] != '?')
                    dp[i][j] = (s[i-1] == p[j-1] && dp[i-1][j-1]);
                else if (p[j-1] == '?')
                    dp[i][j] = dp[i-1][j-1];
                else {
                    dp[i][j] = dp[i][j-1] || dp[i-1][j];
                }
            }
        
        return dp.back().back();
    }
};

和第10题有一些相似的地方的。
然后这一题还是有最优解法,不用dp,但是暂时没有看明白,以后有机会再看吧:

 bool isMatch(string s, string p) {
        int i = 0, j = 0;
        int m = s.length(), n = p.length();
        int last_match = -1, starj = -1;
        while (i < m){
            if (j < n && (s[i] == p[j] || p[j] == '?')){
                i++; j++;
            }
            else if (j < n && p[j] == '*'){
                starj = j;
                j++;
                last_match = i;
            }
            else if (starj != -1){
                j = starj + 1;
                last_match++;
                i = last_match;
            }
            else return false;
        }
        while (p[j] == '*' && j <n) j++;
        return j == n;
    }

主要还是把那个dp的解法看明白

posted @ 2019-09-17 15:15  于老师的父亲王老爷子  阅读(23)  评论(0编辑  收藏  举报