给定一个字符串 (
s
) 和一个字符模式 (p
) ,实现一个支持'?'
和'*'
的通配符匹配。'?' 可以匹配任何单个字符。 '*' 可以匹配任意字符串(包括空字符串)。两个字符串完全匹配才算匹配成功。
说明:
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符?
和*
。
示例 1:
输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入: s = "aa" p = "*" 输出: true 解释: '*' 可以匹配任意字符串。
示例 3:
输入: s = "cb" p = "?a" 输出: false 解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
示例 4:
输入: s = "adceb" p = "*a*b" 输出: true 解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5:
输入: s = "acdcb" p = "a*c?b" 输出: false
给题解的巨巨太强了,一直没想出来怎么回复,这个解法真的得好好消化!!!!
class Solution {
public:
bool isMatch(string s, string p) {
int len = s.size();
int i = 0,j = 0,istart = -1,jstart = -1;
while(i < len){
// 如果s[i]和p[j]相同,继续遍历,或者p[j]等于?,注意p[j]是不能匹配空字符的
if(j < p.size() && (s[i] == p[j] || p[j] == '?')) i++,j++;
else if(j < p.size() && p[j] == '*'){//如果p[j]为*,可以匹配任意字符,假设目前s只匹配第i个位置,然后保存该下标,j往后遍历
istart = i;
jstart = j;
j++;
}
else if(istart >= 0){//如果不匹配而且p[j]也不是*,但istart>=0说明之前有*的存在,只不过匹配的位置有问题,如果是第一次进入该if,这时候的*只匹配了s的第i个字符。因为进入该if,所以之前只匹配第i个字符是错误的,这时候i的下标为istart+1,说明*匹配两个字符,为第一次匹配的i和i+1,如果后面还进入该if,*应该匹配3个字符了,所以这里istart需要加一,但jstart不需要,在*匹配玩之后。它只需要p后面的字符继续判断就好了。
i = istart + 1;
istart++;
j = jstart + 1;
}
else return false;//均不满足 或者j溢出了,也返回false
}
while(j < p.size() && p[j] == '*') j++; //如果i已经到头了,说明这个时候p的前部分已经可以匹配s了,只要判断后面是否都是*,如果有其他字符就不匹配。
return j == p.size();
}
};