题目:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 '’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
''匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
示例 1:
输入:s = “aa” p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
超时版本:
直接分情况讨论,逻辑上比较好弄懂,但是超时了
class Solution {
public:
bool isMatch(string s, string p) {
//滑动窗口kmp算法
int sz=0,pz=0; //两指针
int slen=s.size();
int plen=p.size();
while(sz<s.size())
{
if(p[pz]=='.') //.跳过该选择语句
{
//移动指针直接跳到.*后的位置
if(p[pz+1]=='*'){
pz=pz+2;
sz=slen-plen+pz;
}
else{
sz++;
pz++;
}
}
else if(p[pz+1]=='*')
{
//前一个元素为零个
if(s[sz]!=p[pz] && s[sz]==p[pz+2]){
pz=pz+2;
sz++;
}
else if(s[sz]!=p[pz] && s[sz+1]!=p[pz]){
return false;
}
//前一个元素为多个
else if(s[sz]==p[pz]){
int pz1=pz+2;
//p中*后也有相同的匹配字符
if(p[pz1]==p[pz]){
while(s[sz]==p[pz1]){
sz++;
pz1++;
}
pz=pz1;
}
else{
while(s[sz]==p[pz])
sz++;
pz++;
pz++;
}
}
}
else if(s[sz]!=p[pz])
return false;
else if(s[sz]==p[pz])
{
sz++;
pz++;
}
}
if(pz==plen)
return true;
return false;
}
};
超时样例:
输入:
s = “mississippi”
p = “misisp*.”
输出:
false
问题:
从左往右分析问题,情况较多,且比较复杂
字符后面是否跟着星号会影响结果,分析起来有点复杂。
可以考虑使用动态规划dp
题解来自leetcode的用户——笨猪爆破组
「手画图解」动态规划,需要仔细的分情况讨论
class Solution {
public:
bool isMatch(string s, string p) {
//dp
const int slen = s.size();
const int plen = p.size();
//dp的状态方程(s中前i个是否可以被p中的前j个匹配)
bool dp[slen+1][plen+1];
//fill_n()函数——从迭代器指向的元素开始,将指定数量的元素设置为给定的值。
fill_n(&dp[0][0], (slen + 1) * (plen + 1), false);
// s 和 p 都为空
dp[0][0] = true;
// s 为空,p 不为空
for (int i = 1; i < plen + 1; i++)
{
if (p[i - 1] == '*')
{
dp[0][i] = dp[0][i - 2];
}
}
// s 不为空,p 为空,结果必为 false
// s 不为空,p 不为空
int i,j;
//从后往前推,需分情况讨论
/*转移方程:
dp[i][j]= dp[i-1][j-1] if s[i]==p[j] && i>0 && j>0
dp[i-1][j] if p[j]=='*' s[i]==p[j-1]
dp[i-1][j] if p[j-cou]==p[j-1]
dp[i][j-cou] if s[i]!=p[j-1]
dp[i-1][j-1] if p[j]=='.'
*/
for(i = 1 ; i<slen + 1 ; i++){
for(j = 1 ; j<plen + 1 ; j++){
if (p[j - 1] == s[i - 1] || p[j - 1] == '.')
{
dp[i][j] = dp[i - 1][j - 1];
}
else if (p[j - 1] == '*')
{
if (p[j - 2] == s[i - 1] || p[j - 2] == '.')
{
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j]; // 抵消0次、1次、或者大于1次。
}
else
{
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[slen][plen];
}
};```