【leetCode】44_通配符匹配

dp:

class Solution {
public:
    bool isMatch(string s, string p) {
        //tag 用于dp,tag[i][j]代表s的子串s[0,i-1] 可以匹配 p的子串p[0,j-1]。
        bool ** tag = new bool*[s.length() + 1];
        for (int i = 0; i <= s.length(); i ++){
            tag[i] = new bool [p.length() + 1];
            memset(tag[i], 0, sizeof(bool) * (p.length() + 1));
        }
        //tag[0][0]初始化条件,可以理解成,s和p的子串s[0,-1], p[0,-1]匹配,即两个空串匹配。
        tag[0][0] = true;
        //dp的递推方程是:tag[i][j] = 
        // (1)p[j - 1] == '*', 则为:tag[i - 1][j - 1] || tag[i][j - 1] || tag[i - 1][j];
        // (2)为:tag[i - 1][j - 1] && (p[j - 1] == '?' ? 1: p[j - 1] == s[i - 1])
        for (int j = 1; j <= p.length(); j ++){
            for (int i = 0; i <= s.length(); i ++){
                if (p[j - 1] == '*'){
                    tag[i][j] = (i > 0 ? (tag[i - 1][j - 1]||tag[i - 1][j]): 0) || tag[i][j - 1];
                }
                else if (i != 0){
                    tag[i][j] = tag[i - 1][j - 1] && (p[j - 1] == '?' ? 1: p[j - 1] == s[i - 1]);
                }
            }
        }
        return tag[s.length()][p.length()];
    }
};

带回溯的贪心:

思路是*字符匹配的时候,可以匹配0~无穷多个字符。所以,枚举s串被匹配的字符数量。

方法是匹配到*的时候,记录下s和p的位置s*和p*,给p的位置+1, s位置不变,此时*匹配0个字符,然后s和p继续匹配之后的字符串。如果匹配不成功,回溯,p的匹配位置更改回p*+1,s的位置更改为记录s*+1,此时*匹配1个字符,然后s和p继续匹配之后的字符。依此类推。

class Solution {
public:
    bool isMatch(string s, string p) {
        int scur = 0, pcur = 0, sstar = -1, pstar = -1;
        while(scur != s.length()){
            if (s[scur] == p[pcur] || p[pcur] == '?'){
                scur ++; pcur ++;
            }
            else if (p[pcur] == '*'){
                pstar = pcur ++;
                sstar = scur;
            }
            else if (pstar != -1){
                pcur = pstar + 1;
                scur = ++ sstar;
            }
            else{
                return false;
            }
        }
        while (p[pcur] == '*'){
            pcur ++;
        }
        return pcur == p.length();
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值