Wildcard Matching

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

好吧,我本来觉得二维的dp可以过的,不就m*n嘛,后来发现我天真了,最长的case,s和p竟然都有3w多,网上很多看似提前判断有效长度的代码,虽然可以ac,但是明显不是这个题目所要求的。。。这个题的要求最好情况应该是线性时间完成

首先我想到的是类似正则表达式的方法,直接递归就可以,TLE很严重。。。

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        if(!*p)
            return !*s;
        if(!*s){
            if(!*p)
                return true;
            if(*p=='*')
                return isMatch(s,p+1);
            return false;
        }
        if(*s==*p || *p=='?'){
            return isMatch(s+1,p+1);
        }
        if(*p=='*'){
            while(*p){
                if(*p=='*'){
                    bool flag = isMatch(s+1,p);
                    if(flag)
                        return true;
                    p++;
                }else
                    break;
            }
            return isMatch(s,p);
        }
        return false;
    }
};

接下来,用dp,还是TLE

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        int m = strlen(s);
        int n = strlen(p);
	m++;
	n++;
	vector<bool> v1,v2;
        for(int j=0;j<n;j++){
            v1.push_back(false);
        }
        v1[0] = true;//s="" p=""
        for(int i=1;i<n;i++){
            if(p[i-1]=='*')
                v1[i] = true;
            else
                break;
        }
        for(int i=1;i<m;i++){
            v2.push_back(false);
            for(int j=1;j<n;j++){
                if(p[j-1]=='*'){
		    v2.push_back(v1[j-1] || v2[j-1] || v1[j]);
                }else if(p[j-1]=='?' || s[i-1]==p[j-1]){
                    v2.push_back(v1[j-1]);
                }else
                    v2.push_back(false);
            }
            v1.clear();
            v1.assign(v2.begin(),v2.end());
            v2.clear();
        }
        return v1[n-1];
    }
};

最终缴械投降,投奔大神。。。 大神在此速度跪下

短短几行代码。。。

好吧,看完以后我ac的代码在这里

用rs和rp来分别保存在上一个“*”时的处理情况。。然后如果此时s和p不匹配,则返回到*这里继续处理,即表明这个字符应该和当前这个"*"匹配,然后将s和p再恢复到rs和rp向后的情况。

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        const char* rs=NULL;
        const char* rp = NULL;
        while(*s){
            if(*s==*p || *p=='?'){
                s++;
                p++;
                continue;
            }
            if(*p=='*'){
                rs = s;
                rp = p;
                p++;//不用这个* 
                continue;
            }
            if(rp!=NULL){
                s = ++rs;
                p = rp+1;
                continue;
            }
            return false;
        }
        while(*p=='*')
            p++;
        return !*p;
    }
};

164ms accept

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值