10. 正则表达式匹配
题目
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
’.’ 匹配任意单个字符
’*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
来源:力扣(LeetCode)
链接:leetcode10
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一、思路
太菜了,不会。借用大佬思路:
leetcode10:题解
dp[i][j]: s的前i-1位 和 p的前j-1位 是否匹配
从右向左分析
-
匹配上了:
s[i-1]==p[j-1] ||p[j-1]=='.'
则dp[i][j]=dp[i-1][j-1];
-
匹配不上:
2.1p[j-1]!='*'
直接匹配不上,return false;
2.2 否则有三种方式:考察p[j-2]重复次数模式串*的前一个字符能够跟文本串的末位匹配上: 0次: dp[i][j-2] 如:s=aab,p=aabb* 1次: dp[i-1][j-2] 如:s=aab,p=aab* >1次:dp[i-1][j] 如:s=aabb,p=aab*(相当于删掉s的最后一个b) 模式串*的前一个字符不能跟文本串的末位匹配上: 0次: dp[i][j-2] 如:s=aa,p=aab*
也可以把>=1看作一种
这种情况下是dp[i-1][j]
二、代码
1.初始化
代码如下(示例):
// s为空,p为空,能匹配上
dp[0][0]=true;
// p为空,s不为空,必为false(boolean数组默认值为false,无需处理)
// s为空,p不为空,由于*可以匹配0个字符,所以有可能为true
for(int j=1;j<=p.size();j++)
{
if(p[j]=='*')
{
dp[0][j+1]=dp[0][j-1];
}
}
2.最终代码
代码如下(示例):
class Solution {
public:
bool isMatch(string s, string p) {
vector<vector<char>>dp(s.size()+1,vector<char>(p.size()+1,false));
// s为空,p为空,能匹配上
dp[0][0]=true;
// p为空,s不为空,必为false(boolean数组默认值为false,无需处理)
// s为空,p不为空,由于*可以匹配0个字符,所以有可能为true
for(int j=1;j<=p.size();j++)
{
if(p[j]=='*')
{
dp[0][j+1]=dp[0][j-1];
}
}
for(int i=1;i<=s.size();i++)
{
for(int j=1;j<=p.size();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] || dp[i - 1][j];
// 匹配0次的情况&&1次或多次的情况
}
else
{
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[s.size()][p.size()];
}
};
**小tips:**
题目保证 p[0]!="*"
所以,不会出现 dp[0][j-2]=dp[0][-1]
这种情况。这种情况的发生,只可能发生在
j==1 && p[j-1]== "*"
此时,p[0]="*"
。
总结
初始化那里还搞了一会,得想明白才行。
第一次写blog呜呜呜,感觉写的好烂(