题目描述:
Given an input string (s
) and a pattern (p
), 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).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like?
or*
.
Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "*"
Output: true
Explanation: '*' matches any sequence.
Example 3:
Input:
s = "cb"
p = "?a"
Output: false
Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.
Example 4:
Input:
s = "adceb"
p = "*a*b"
Output: true
Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".
Example 5:
Input:
s = "acdcb"
p = "a*c?b"
Output: false
算法描述:
递归回溯法---超时
虽然经过多方面的优化,将前后匹配的元素去掉,将中间‘*’重复的去掉等
class Solution {
public:
bool isMatch(string s, string p) {
int slen = s.length(),plen = p.length();
int i = 0;
while(i < slen && i < plen && p[i] != '*' ){
if(p[i] != '?' && p[i] != s[i])return false;
i ++;
}
int j = 0;
while(j < slen - i && j < plen -i && p[plen - j - 1] != '*' ){
if(p[plen - j - 1] != '?' && p[plen - j - 1] != s[slen - j - 1])
{
return false;
}
j ++;
}
s = s.substr(i, slen - j);
p = p.substr(i, plen - j);
// cout << s << endl;
// cout << p << endl;
for(int i = p.length() - 2; i >= 0; i --){
if(p[i] == '*' && p[i + 1] == '*')p.erase(i,1);
}
// cout << s << endl;
// cout << p << endl;
return isMatch(s, s.length() - 1, p, p.length() - 1);
}
bool isMatch(string s, int i, string p, int j){
if(j == -1){
if(i == -1)return true;
else return false;
}
if(i >= 0 && (s[i] == p[j] || p[j] == '?'))
return isMatch(s, i - 1, p, j - 1);
if(p[j] == '*')
{
while(i >= -1){
if(p[j - 1] == '?' || s[i] == p[j - 1]){
if(isMatch(s, i , p, j - 1))
return true;
}
i --;
}
return false;
}
return false;
}
};
采用动态规划的方法,与前面第10题相似
不同的是其中优化了一点,当p中为‘*’与s中某个位置i的元素匹配后,那么p中到‘*’这个位置,可以与s中i及i以后所有的位置匹配
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.length();
int n = p.length();
bool b[m + 1][n + 1];
b[0][0] = true;
for(int i = 1; i <= m ; i ++)b[i][0] = false;
for(int j = 1; j <= n ; j ++)b[0][j] = p[j - 1] == '*' && b[0][j - 1];
for(int j = 1; j <= n; j ++)
for(int i = 1; i <= m; i ++)
{
if(p[j - 1] == '*')
{
b[i][j] = false;
for(int k = i; k >= 0; k --)
if(b[k][j - 1]){
b[i][j] = true;
break;
}
if(b[i][j]){
for(int t = i; t <= m; t ++ )b[t][j] = true;
}
}
else{
if(p[j - 1] == '?' || p[j - 1] == s[i - 1])b[i][j] = b[i - 1][j - 1];
else b[i][j] = false;
}
return b[m][n];
}
};