题意:
给两个字符串,s和p,s只包含小写字母,p包含小写字母或 ‘.’ ,‘*’。前者可以匹配任意单一字符,后者表示前面的字符重复次数,可以是0次或无数次。
思路:
动态规划。
代码:
class Solution {
public:
bool isMatch(string s, string p) {
int lens = s.length();
int lenp = p.length();
vector<vector<bool> >dp(lenp+1, vector<bool>(lens+1, false));
dp[0][0] = true;
if (lenp >= 1) dp[1][0] = false;
for (int i=2; i<=lenp; ++i) {
if (p[i-1] == '*') dp[i][0] = dp[i-2][0];
}
for (int i=1; i<=lenp; ++i) {
for (int j=1; j<=lens; ++j) {
if (p[i-1] == s[j-1] || p[i-1] == '.') dp[i][j] = dp[i-1][j-1];
else if (p[i-1] == '*') {
dp[i][j] = dp[i-2][j];
if (p[i-2] == s[j-1] || p[i-2] == '.') dp[i][j] = (dp[i][j] || dp[i][j-1]);
}
}
}
return dp[lenp][lens];
}
};
#############################################
第二次遇见。只会写记忆化搜索。。。
class Solution {
public:
bool isMatch(string s, string p) {
return match(s, p, 0, 0);
}
bool match(string s, string p, int i, int j) {
if (i == s.length() && j == p.length()) return true;
if (j >= p.length()) return false;
if (mp.count({i, j})) return mp[{i, j}];
bool res = false;
if (j < p.length()-1 && p[j+1] == '*') {
if ((s[i] == p[j] || p[j] == '.') && i < s.length()) {
res |= match(s, p, i+1, j);
res |= match(s, p, i+1, j+2);
}
res |= match(s, p, i, j+2);
}else if ((s[i] == p[j] || p[j] == '.') && i < s.length()) {
res |= match(s, p, i+1, j+1);
}
return mp[{i, j}] = res;
}
private:
map<pair<int, int>, bool> mp;
};