1、递归
具体思路同LeetCode-剑指19-正则表达式匹配,但在本题中由于字符串长度过长会导致超时。
在这里插入代码片class Solution {
public:
bool isMatch(string s, string p) {
if (p.empty()) return s.empty();
bool first_match = !s.empty() && (s[0] == p[0] || p[0] == '?' || p[0] == '*');
if (p[0] == '*') {
return (first_match && isMatch(s.substr(1), p)) || isMatch(s, p.substr(1));
} else {
return first_match && isMatch(s.substr(1), p.substr(1));
}
}
};
2、动态规划法
我们可以利用二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j]来表示字符串 s s s的前 i i i位与字符串 p p p的前 j j j位的匹配情况。我们首先需要对二维数组进行初始化,其中 d p [ 0 ] [ 0 ] = t r u e dp[0][0] = true dp[0][0]=true,当字符串 p p p的前 j j j位均为 “ ∗ ” “*” “∗”时同样 d p dp dp值为 t r u e true true。而后我们进行循环:1、若 p [ j − 1 ] = = ′ ? ′ 或 s [ i − 1 ] = = p [ j − 1 ] p[j - 1] == '?' 或 s[i - 1] == p[j - 1] p[j−1]==′?′或s[i−1]==p[j−1],说明此时这一位上两个字符串是匹配的,故具体的值取决于此前的字符串是否匹配;2、若 p [ j − 1 ] = = ′ ∗ ′ p[j - 1] == '*' p[j−1]==′∗′,说明此时可能出现两种情况,一是 “ ∗ ” “*” “∗”匹配空字符串,故此时的状态与 d p [ i ] [ j − 1 ] dp[i][j - 1] dp[i][j−1]相同,二是 “ ∗ ” “*” “∗”匹配任意一个字符,此时的状态与 d p [ i − 1 ] [ j ] dp[i - 1][j] dp[i−1][j]的状态相同。
class Solution {
public:
bool isMatch(string s, string p) {
vector<vector<bool>> dp(s.size() + 1, vector<bool>(p.size() + 1));
dp[0][0] = true;
for (int i = 1; i <= p.size(); ++i) {
if (p[i - 1] == '*') dp[0][i] = true;
else break;
}
for (int i = 1; i <= s.size(); ++i) {
for (int j = 1; j <= p.size(); ++j) {
if (p[j - 1] == '?' || s[i - 1] == p[j - 1]) dp[i][j] = dp[i - 1][j - 1];
if (p[j - 1] == '*') dp[i][j] = dp[i][j - 1] | dp[i - 1][j];
}
}
return dp[s.size()][p.size()];
}
};
3、贪心算法
我们可以将字符串 p p p认为是可以根据 “ ∗ ” “*” “∗”分割后的多个字符串,若在原来的字符串 s s s中包含这些字符串则说明两个字符串是匹配的。在此我们还需要考虑两种特殊情况:1、字符串 p p p不以 “ ∗ ” “*” “∗”作为结尾,此时我们可以先从后向前进行遍历直至以 “ ∗ ” “*” “∗”作为结尾;2、字符串 p p p不以 “ ∗ ” “*” “∗”作为开头,此时我们利用 s R e c o r d sRecord sRecord和 t R e c o r d tRecord tRecord标记为-1表示不能继续重新匹配。
class Solution {
public:
bool isMatch(string s, string p) {
auto allStars = [](const string& str, int left, int right) {
for (int i = left; i < right; ++i) {
if (str[i] != '*') {
return false;
}
}
return true;
};
auto charMatch = [](char u, char v) {
return u == v || v == '?';
};
while (s.size() && p.size() && p.back() != '*') {
if (charMatch(s.back(), p.back())) {
s.pop_back();
p.pop_back();
}
else {
return false;
}
}
if (p.empty()) {
return s.empty();
}
int sIndex = 0, pIndex = 0;
int sRecord = -1, pRecord = -1;
while (sIndex < s.size() && pIndex < p.size()) {
if (p[pIndex] == '*') {
++pIndex;
sRecord = sIndex;
pRecord = pIndex;
}
else if (charMatch(s[sIndex], p[pIndex])) {
++sIndex;
++pIndex;
}
else if (sRecord != -1 && sRecord + 1 < s.size()) {
++sRecord;
sIndex = sRecord;
pIndex = pRecord;
}
else {
return false;
}
}
return allStars(p, pIndex, p.size());
}
};