题意
一个目标串S,一个模式串P,判断二者是否匹配,其中几种匹配规则
- ’ . ‘可以表示任意的单个字符
- ’ * ‘可以代表它之前的字符的任意个数,可以为0或者更多
几个例子:
- isMatch(“aa”,”a”) → false
- isMatch(“aa”,”aa”) → true
- isMatch(“aaa”,”aa”) → false
- isMatch(“aa”, “a*”) → true
- isMatch(“aa”, “.*”) → true
- isMatch(“ab”, “.*”) → true
- isMatch(“aab”, “c*a*b”) → true
感觉应该解释一下最后一组样例,因为第一次看的时候没看懂,”c*a*b”可以写成”c0a2b”,那么得出的字符串中’ * ‘代表即为0个c,2个a,结果匹配.
思路
i
代表S串的位置下标,
- S串遍历完成
- P串遍历完成, 匹配成功
- P串未遍历完成,如果 j+1 位置的字符为*,检查 j+2 后面的字符串是否匹配,否则匹配不成功
- S串遍历未完成
- P串遍历完成,匹配不成功
- P串未遍历完成
-
j+1
位置的字符不为*,如果
i
处字符和
j 处字符匹配(包括 j 处字符为’ . ‘的情况),继续递归向下检查i+1 和 j+1 后面的字符串,否则匹配不成功 -
j+1
位置的字符为,如果
i
处字符和
j 处字符无法匹配(包括 j 处字符为’ . ‘的情况),那么递归检查i 和 j+2 后面的字符串,如果检查成功,那么匹配成功,否则也需要递归检查 i 和 j+2 后面的字符串,如果检查成功,那么匹配成功,否则要暴力检查S串和P串是否匹配,其实这里的暴力是为了检查能够匹配几个前面的字符,期间如果有一个能够检查成功,即为匹配成功。
-
j+1
位置的字符不为*,如果
i
处字符和
结果
很尴尬啊!!!
Your runtime beats 6.74 % of cpp submissions.
代码
class Solution {
public:
bool isMatch(string s, string p) {
return check(0, 0, s, p);
}
bool check(size_t i, size_t j, string s, string p){
if(i == s.length()){
if(j == p.length()) return true;
if(p[j + 1] == '*') return check(i, j + 2, s, p);
else return false;
} else{
if(j == p.length()) return false;
if(p[j + 1] != '*'){
if(s[i] == p[j] || p[j] == '.') return check(i + 1, j + 1, s, p);
return false;
} else{
if(s[i] != p[j] && p[j] != '.') return check(i, j + 2, s, p);
if(check(i, j + 2, s, p)) return true;
size_t k = 0;
while(k + i + 1 <= s.length() && (s[k + i] == p[j] || p[j] == '.')){
if(check(k + i + 1, j + 2, s, p))
return true;
k++;
}
return false;
}
}
}
};