力扣https://leetcode-cn.com/problems/regular-expression-matching/
方法一:动态规划法
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size() + 1, n = p.size() + 1;
vector<vector<bool>> dp(m, vector<bool>(n, false));
dp[0][0] = true;
// 初始化首行
for(int j = 2; j < n; j += 2)
dp[0][j] = dp[0][j - 2] && p[j - 1] == '*';
// 状态转移
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
if(p[j - 1] == '*') {
if(dp[i][j - 2]) dp[i][j] = true; // 1.
else if(dp[i - 1][j] && s[i - 1] == p[j - 2]) dp[i][j] = true; // 2.
else if(dp[i - 1][j] && p[j - 2] == '.') dp[i][j] = true; // 3.
} else {
if(dp[i - 1][j - 1] && s[i - 1] == p[j - 1]) dp[i][j] = true; // 1.
else if(dp[i - 1][j - 1] && p[j - 1] == '.') dp[i][j] = true; // 2.
}
}
}
return dp[m - 1][n - 1];
}
};
其实题解的s的下标实在是难以理解导致大部分同学理解题解困难,其实只要在s和p前面都加上一个字符,就能很愉快地解决下标理解的问题
如下代码
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size() + 1, n = p.size() + 1;
vector<vector<bool>> dp(m, vector<bool>(n, false));
// 下标向后推移1
s = "0" + s;
p = "0" + p;
dp[0][0] = true;
for (int j = 2; j < n; j += 2) {
// null pattern
dp[0][j] = dp[0][j-2] && p[j] == '*';
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (p[j] == '*') {
dp[i][j] = (
dp[i][j-2]
|| dp[i-1][j] && s[i] == p[j-1]
|| dp[i-1][j] && p[j-1] == '.'
);
} else {
dp[i][j] = (
dp[i-1][j-1] && s[i] == p[j]
|| dp[i-1][j-1] && p[j] == '.'
);
}
}
}
// for (int i = 0; i < m; i++) {
// for (int j = 0; j < n; j++) {
// cout<<dp[i][j]<<" ";
// }
// cout<<endl;
// }
return dp[m-1][n-1];
}
};
class Solution {
public:
bool isMatch(string s, string p) {
s=" "+s;//防止该案例:""\n"c*"
p=" "+p;
int m=s.size(),n=p.size();
vector<vector<bool>> dp(m+1,vector<bool>(n+1,false));
// bool dp[m+1][n+1];
// memset(dp,false,(m+1)*(n+1));
dp[0][0]=true;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(s[i-1]==p[j-1] || p[j-1]=='.'){
dp[i][j]=dp[i-1][j-1];
}
else if(p[j-1]=='*'){
if(s[i-1]!=p[j-2] && p[j-2]!='.')
dp[i][j]=dp[i][j-2];
else{
dp[i][j]=dp[i][j-1] || dp[i][j-2] || dp[i-1][j];
}
}
}
}
return dp[m][n];
}
};
方法二:迭代法
substr的用法https://blog.csdn.net/Dejan520/article/details/123571003?spm=1001.2014.3001.5501
#include <vector>
#include <string>
using namespace std;
class Solution
{
public:
bool isMatch(string s, string p)
{
if (p.empty())
{
return s.empty();
}
if ('*' == p[1])
{
return isMatch(s, p.substr(2)) || (!s.empty() && (s[0] == p[0] || '.' == p[0]) && isMatch(s.substr(1), p));
}
else
{
return !s.empty() && (s[0] == p[0] || '.' == p[0]) && (isMatch(s.substr(1), p.substr(1)));
}
}
};