本文仅仅记录自身代码的一步步演变过程,需要详细解答请前往官网查看
一、 纯递归求解
class Solution {
public:
bool Match(string &s,string &p,int start_s,int start_p){
int size_s = s.size(),size_p = p.size(),i = start_s, j = start_p;
if(j == size_p) return i == size_s;
if(i < size_s && (j == size_p - 1 || p[j + 1] != '*')){
if(p[j] != '.')
return s[i] == p[j] && Match(s,p,i + 1, j + 1);
else{
return Match(s,p,i + 1, j + 1);
}
}
//p串第二位为 '*'
if(j + 1 < size_p && p[j + 1] == '*') {// p串第二位为 '*'
bool notuse = Match(s,p,i,j + 2);
bool use = i == size_s ? false : ( (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1,j) );
return notuse || use;
}
//s 串已空 且 p串为单次匹配
return false;
}
bool isMatch(string s, string p) {
int size_s = s.size(),size_p = p.size(),i = 0, j = 0;
return Match(s,p,0,0);
}
};
时间复杂度过高,考虑用一个数组记录搜索分支的结果,遇到相同分支直接返回
二、用数组记录中途搜索结果进行优化
自顶向下
class Solution {
public:
bool Match(string &s,string &p,int start_s,int start_p,vector<vector<int>> &dp){
int size_s = s.size(),size_p = p.size(),i = start_s, j = start_p;
if(dp[i][j] != 0) return dp[i][j] > 0;
if(j == size_p) {
dp[i][j] = i == size_s ? 1 : -1;
return dp[i][j] > 0;
}
if(i < size_s && (j == size_p - 1 || p[j + 1] != '*')){
dp[i][j] = (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1, j + 1,dp) ? 1 : -1;
return dp[i][j] > 0;
}
//p串第二位为 '*'
if(j + 1 < size_p && p[j + 1] == '*') {// p串第二位为 '*'
bool notuse = Match(s,p,i,j + 2,dp);
bool use = i == size_s ? false : ( (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1,j,dp) );
dp[i][j] = notuse || use ? 1 : -1;
return dp[i][j] > 0 ;
}
//s 串已空 且 p串为单次匹配
dp[i][j] = -1;
return false;
}
bool isMatch(string s, string p) {
int size_s = s.size(),size_p = p.size(),i = 0, j = 0;
vector<vector<int>> dp(size_s + 1,vector<int>(size_p + 1,0));// 0 表示未访问, 1 表示 匹配,-1 表示不匹配
return Match(s,p,0,0,dp);
}
};
三、动态规划(自底向上)
class Solution {
public:
bool isMatch(string s, string p) {
int size_s = s.size(),size_p = p.size();
vector<vector<bool> > dp ( size_s + 1,vector<bool>(size_p + 1,false) );
//自底向上
dp[size_s][size_p] = true;
for(int i = size_s; i >= 0; i--){
for(int j = size_p - 1; j >= 0;j--){
bool first_match = i < size_s && (p[j] == '.' || s[i] == p[j]); // 首字母匹配
if(j + 1 < size_p && p[j + 1] == '*'){
dp[i][j] = dp[i][j + 2] || (first_match && dp[i + 1][j]);
}else{
dp[i][j] = first_match && dp[i + 1][j + 1];
}
}
}
return dp[0][0];
}
};