Leetcode-10.正则表达式匹配

题目描述

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

1
2
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

解法 1:动态规划

1.状态

$dp[i][j]$表示s的前i个字符,p的前j个字符,能否匹配(i<=n,j<=m,n=s.length(),m=p.length())

2.转移方程

1)如果s的第 i 个字符和p的第 j 个字符相同,或者s2的第 j 个字符为 “.”

p[j]==s[i]||p[j]==’.’:dp[i][j]=dp[i-1][j-1] //如果

2)p[j]==’*’:

  • p[j-1]!=s[i]:dp[i][j]=dp[i][j-2]

  • p[j-1]==s[i]||p[j-1]==’.’:

    • dp[i][j]=dp[i-1][j]// a*与多个a匹配
    • dp[i][j]=dp[i][j-1]//a*与一个a匹配
    • dp[i][j]=dp[i][j-2]//a*与0个a匹配

ps:只写dp[i-1][j]和dp[i][j]也可以,思考一下

3.初始化

dp[0][0]=true

dp[0][j]=dp[0][j-2]if(j==’*’)

s的前0个字符和p的前j个字符能否匹配

4.结果

dp[n][m]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
bool isMatch(string s, string p) {
int n=s.length();
int m=p.length();
vector<vector<bool>> dp(n+1,vector<bool>(m+1,false));
dp[0][0]=true;
int i,j;
for(j=2;j<=m;j++)
{
dp[0][j]=dp[0][j-2]&&p[j-1]=='*';
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{

if(s[i-1]==p[j-1]||p[j-1]=='.')
dp[i][j]=dp[i-1][j-1];
if(p[j-1]=='*')
{
dp[i][j]=dp[i][j-2]||(p[j-2]==s[i-1]||p[j-2]=='.')&&(dp[i-1][j]);
}
}
}
return dp[n][m];
}
};