LeeCode 10 DFS / DP

58 篇文章 0 订阅
题意

传送门 LeeCode 10. 正则表达式匹配

题解
DFS

对于 ′ a − z ′ 'a-z' az ′ . ′ '.' . 只需判断字符串 s s s 与字符规律 p p p 的当前字符是否匹配,若匹配成功 s , p s,p s,p 指针移动至下一位置匹配后续字符;反之,匹配失败。

考虑到 ′ ∗ ′ '*' 匹配零个或多个前面的那一个元素,则若 p p p 当前匹配字符的下一字符为 ′ ∗ ′ '*' ,则可以匹配或不匹配当前字符,根据回溯结果判断匹配结果。

class Solution
{
public:
    bool match(string &s, string &p, int i, int j)
    {
        if (j == p.length()) return i == s.length();
        bool f = (i < s.length() && (s[i] == p[j] || p[j] == '.'));
        if (j + 1 < p.length() && p[j + 1] == '*')
        {
            return match(s, p, i, j + 2) || (f ? match(s, p, i + 1, j) : f);
        }
        return f ? match(s, p, i + 1, j + 1) : f;
    }
    bool isMatch(string s, string p)
    {
        return match(s, p, 0, 0);
    }
};
DP

d f s dfs dfs 的思考写为递推式, d p [ i ] [ j ] dp[i][j] dp[i][j] 代表字符规律 p p p 的区间 [ 0 , i − 1 ] [0,i-1] [0,i1] 与字符串 s s s 的区间 [ 0 , j − 1 ] [0,j-1] [0,j1] 匹配的结果, f l a g flag flag 判断字符是否匹配
f l a g = { 1 j = = 0   ∣ ∣   p [ i − 1 ] = = ′ . ′   ∣ ∣   p [ i − 1 ] = = s [ j − 1 ] 0 o t h e r w i s e flag=\begin{cases} 1 & j==0\ ||\ p[i-1]=='.'\ ||\ p[i-1]==s[j-1]\\ 0 & otherwise\\ \end{cases} flag={10j==0  p[i1]==.  p[i1]==s[j1]otherwise

{ i f ( p [ i − 1 ] = = ′ ∗ ′ ) c o n t i n u e e l s e   i f ( p [ i ] = = ′ ∗ ′ ) d p [ i + 1 ] [ j ] { d p [ i − 1 ] [ j − 1 ]   ∣ ∣   d p [ i + 1 ] [ j − 1 ]   ∣ ∣   d p [ i − 1 ] [ j ] f l a g = 1 d p [ i − 1 ] [ j ] o t h e r w i s e   e l s e d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] f l a g = 1 f a l s e o t h e r w i s e \begin{cases} if(p[i-1]=='*') & continue\\ else\ if(p[i]=='*')& dp[i+1][j]\begin{cases} dp[i-1][j-1]\ ||\ dp[i+1][j-1]\ ||\ dp[i-1][j]&flag=1\\ dp[i-1][j] & otherwise \\ \end{cases}\ \\ else& dp[i][j]=\begin{cases} dp[i-1][j-1]&flag=1\\ false& otherwise\end{cases}\\ \end{cases} if(p[i1]==)else if(p[i]==)elsecontinuedp[i+1][j]{dp[i1][j1]  dp[i+1][j1]  dp[i1][j]dp[i1][j]flag=1otherwise dp[i][j]={dp[i1][j1]falseflag=1otherwise

class Solution
{
public:
    bool judge(char p, char s)
    {
        return s == 'X' ? 0 : (p == '.' || p == s);
    }
    bool isMatch(string s, string p)
    {
        int n = p.length(), m = s.length();
        vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, 0));
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++)
        {
            if (p[i - 1] == '*')
                continue;
            if (i == n || p[i] != '*')
            {
                for (int j = 1; j <= m; j++)
                {
                    dp[i][j] = judge(p[i - 1], s[j - 1]) ? dp[i - 1][j - 1] : 0;
                }
            }
            else
            {
                for (int j = 0; j <= m; j++)
                {
                    dp[i + 1][j] = judge(p[i - 1], j == 0 ? 'X' : s[j - 1]) ? (dp[i - 1][j - 1] || dp[i + 1][j - 1] || dp[i - 1][j]) : dp[i - 1][j];
                }
            }
        }
        return dp[n][m];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值