1. 程式人生 > >[LeetCode]Wildcard Matching 通配符匹配(貪心)

[LeetCode]Wildcard Matching 通配符匹配(貪心)

復雜度 能夠 sts als [0 popu tco ret lee

一開始採用遞歸寫。TLE。

class Solution {
public:
	bool flag;
	int n,m;
	void dfs(int id0,const char *s,int id1,const char *p){
		if(flag)return;
		if(id0>=n){
			if(id1>=m)flag=1;
			else{
				int j=0;
				while(j<m&&p[j]=='*')j++;
				if(j>=m)flag=1;
			}
			return;
		}
		else if(id1>=m)return;
		if(p[id1]=='?

'||p[id1]==s[id0]){ dfs(id0+1,s,id1+1,p); } else if(p[id1]=='*'){ for(int j=id0;j<n;++j) dfs(j,s,id1+1,p); } } bool isMatch(const char *s, const char *p) { for(n=0;s[n];++n); for(m=0;p[m];++m); flag=0; dfs(0,s,0,p); return flag; } };


粗剪枝了,還是超時。


看了下Discuss,發現能夠貪心:

class Solution {
public:
	bool isMatch(const char *s, const char *p) {
		const char*lastp=NULL,*lasts=NULL;
		while(*s){
			if(*s==*p||*p=='?'){
				p++;
				s++;
			}
			else if(*p=='*'){
				//不匹配,僅僅記錄
				lastp=p++;
				lasts=s;
			}
			else if(lastp!=NULL){
				p=lastp+1;
				s=++lasts;//逐漸遞增匹配1個字符、2個字符...
			}
			else return false;
		}
		while(*p&&*p=='*')p++;
		return *p=='\0';
	}
};

採用DP:

用dp[i,j]表示s[0,..,i]與p[0,..,j]是否匹配

dp[i,j]=1 if (p[j]==‘*‘&&(dp[i-1,j]||dp[i][j-1]||dp[i-1][j-1]))

dp[i,j]=1 if ((p[j]==‘?‘||s[i]==p[j]])&&dp[i-1][j-1])

時間復雜度O(nm),能夠採用滾動數組,否則會超內存。空間復雜度O(m)

可是,會超時

bool isMatch(const char *s, const char *p) {
		int n=strlen(s),m=strlen(p),i,j;
		bool **dp=new bool*[2];
		for(i=0;i<2;++i){
			dp[i]=new bool[m+1];
			memset(dp[i],0,sizeof(bool)*(m+1));
		}
		dp[0][0]=1;
		bool flag=0;
		for(i=1;i<=n;++i){
			for(j=1;j<=m;++j){
				if(dp[flag][j-1]&&(p[j-1]=='?'||s[i-1]==p[j-1]))
					dp[1-flag][j]=1;
				else if(p[j-1]=='*'&&(dp[flag][j-1]||dp[flag][j]||dp[1-flag][j-1]))
					dp[1-flag][j]=1;
			}
			flag=1-flag;
		}
		bool ans=dp[1][m];
		for(i=0;i<2;++i)delete[] dp[i];
		delete[]dp;
		return ans;
	}


[LeetCode]Wildcard Matching 通配符匹配(貪心)