44. 通配符匹配/C++

44. 通配符匹配/C++_第1张图片

动态规划

dp[i][j]表示s的前i个字符与p的前j个字符是否匹配。

bool isMatch(string s, string p) {
	size_t m = s.size(), n = p.size();
	vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
	
	dp[0][0] = true;
	//初始化,p的前j个字符与空字符串匹配,只有当p的前面为*时,才能匹配
	for (size_t j = 1; j <= n; ++j)
		if (p[j - 1] == '*')
			dp[0][j] = dp[0][j - 1];
	//至于dp[i][0]表示空字符模式与字符串s匹配,显然是不能匹配的,因此都是false,不需要再额外处理
	
	for (size_t i = 1; i <= m; ++i) 
		for (size_t j = 1; j <= n; ++j) 
			//如果最后一个字符匹配,或者模式的最后一个字符为?
			if (s[i - 1] == p[j - 1] || p[j - 1] == '?')
				dp[i][j] = dp[i - 1][j - 1];
			//模式的最后一个字符为*,则*可以匹配0个字符(dp[i][j - 1]),也可以匹配多个字符(dp[i - 1][j])
			//虽然dp[i - 1][j]表面上是只匹配了一个字符,
			//但是dp[i-1][j] = dp[i - 2][j] || dp[i-1][j - 1];可以多层嵌套以表示匹配多个字符
			else if (p[j - 1] == '*')
				dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
		
	return dp[m][n];
}

双指针

bool isMatch(string s, string p) {
	size_t i=0,j=0,start_s=-1,start_p=-1;
    while(i<s.size()){
    	//匹配后,两个指针都往后移
        if(j<p.size() && (s[i]==p[j] || p[j]=='?')){
            ++i;
            ++j;
        //有*,则记录下两个指针的位置,暂且让*匹配空字符(++j)
        }else if(j<p.size() && p[j]=='*'){
            start_p = j;
            start_s = i;
            ++j;
        //如果不匹配也不是*,而且之前有*(start_p存的就是*的位置),则j回到*的后面,i回到start_s的后面(表示让*多匹配一个字符)
        }else if(start_p != -1){
            j = start_p + 1;
            i = ++start_s;
        }else{
        	//字符不匹配也没有*,返回
            return false;
        }
    }
    
    //将末尾多余的*匹配空字符
    while(j<p.size() && p[j]=='*')
        ++j;
    
    return j == p.size();
}

你可能感兴趣的:(双指针,动态规划,LeetCode/C++)