问题描述
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
示例1:
输入:s = “aa” p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例2:
输入:s = “aa” p = “a*”
输出:true
解释:因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例3:
输入:s = “ab” p = “."
输出:true
解释:".” 表示可匹配零个或多个(’*’)任意字符(’.’)。
示例4:
输入:s = “aab” p = “cab”
输出:true
解释:因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
示例5:
输入:s = “mississippi” p = “misisp*.”
输出:false
- 0 <= s.length <= 20
- 0 <= p.length <= 30
- s 可能为空,且只包含从 a-z 的小写字母。
- p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
- 保证每次出现字符 * 时,前面都匹配到有效的字符
解法
我的想法:暴力求解,判断*位置,前面多个字符0次多次不知道如何处理,多个星号时不知道如何处理,以及存在.的时候不知道如何将字符串进行匹配。
class Solution {
public:
bool isMatch(string s, string p) {
int lens=s.size();
int lenp=p.size();
vector<vector<bool>> dp(lens+1,vector<bool>(lenp+1,false));//因为包含了空字串的情况
//初始化
dp[0][0]=true;//两个空字串
for(int j=1;j<lenp+1;j++)//找出s为空 但p因为* 为空的情况
{
if(p[j]=='*')
{
dp[0][j+1]=dp[0][j-1];
}
}
//更新
for(int i=1;i<lens+1;i++)
{
for(int j=1;j<lenp+1;j++)
{
if(s[i-1]==p[j-1]||p[j-1]=='.')//情况1:符合,直接更新
{
dp[i][j]=dp[i-1][j-1];
}
else if(p[j-1]=='*')//情况2:考虑*的情况
{
if(s[i-1]==p[j-2]||p[j-2]=='.')
{
dp[i][j]=dp[i][j-2]||dp[i-1][j-2]||dp[i-1][j];//分别是 重复0次;重复一次;重复两次及以上!!!
}
else//s[i-1] p[j-2]不匹配 *需要重复0次
{
dp[i][j]=dp[i][j-2];
}
}
}
}
return dp[lens][lenp];
}
};
虽然看解析能够看明白,可是程序的完整运行过程仍然不熟悉,状态转移过程中二维数组值如歌确定不太清晰。