leetcode 10 Regular Expression Matching

问题

https://leetcode.com/problems/regular-expression-matching/

方法一 回溯(24ms)

class Solution {
public:
    bool sol(const char *s, const char * p)
    {
        if (*p == 0)
            return *s==0;

        if (*(p+1) == '*')
        {
            while(1) // ?* 先匹配0个或多个,然后递归
            {
                if (sol(s, p+2))
                    return true;
                if (*s && (*s == *p || *p =='.'))
                    s++;
                else
                    break;
            }
            return false;  // 当 ?* 不能匹配时 说明不满足
        }else{
           return (*s &&(*s == *p || *p =='.')) && sol(s+1, p+1);
        }
    }
    bool isMatch(string s, string p) {
        return sol(s.c_str(), p.c_str());
    }
};

注意按照p分情况讨论,p+1为* 时,依次判断0~n次。
最坏复杂度分析:
最坏情况举例 p = “.*.*.*.*.*x “, s = “abcdefgh”
复杂度为len(p) = m (.* 看做一个), len(s) = n
O( nm )

方法二 dp (4ms)

class Solution {
public:
    bool isMatch(string s, string p) {
        bool dp[2][p.size() + 1];
        memset(dp, 0, sizeof(dp));
        int cur = 0;
        dp[cur][0] = true;

        for (int i=0; i< p.size(); i++)
            if (p[i]== '*')
                dp[cur][i+1] = dp[cur][i] = dp[cur][i-1]; 

        for (int i=0; i< s.size(); i++)
        {
            cur = !cur;
            dp[cur][0] = false;
            for (int j= 0; j< p.size(); j++)
            {
                if (p[j]!= '*')
                {
                    if (j+1 <p.size() && p[j+1]=='*')
                    {
                        dp[cur][j+1] = dp[cur][j] || ((dp[!cur][j] || dp[!cur][j+1]) && (p[j]=='.'||s[i]==p[j]));
                    }
                    else
                        dp[cur][j+1] = dp[!cur][j] && (p[j]=='.' || s[i]==p[j]);
                }else{
                    dp[cur][j+1] = dp[cur][j] ;
                }
            }
        }

        return dp[cur][p.size()];
    }
};

将s中的每个字符看做一个阶段,定义状态f(i, j) 为原串s的0~i个字符与模式串p的 0~j 个字符是否匹配。
状态转移方程:
如果p[j+1 ] != ‘*’ f(i, j) = f(i-1, j-1) && p[j] == s[i];
如果p[j+1] == ‘*’ f(i, j) = f(i, j-1) 《 匹配0个》 | f(i-1, j-1) && p[j] == s[i] 《 匹配1个》| f(i-1, j) && p[j] == s[i] 《匹配>= 2个》;
如果p[j] = ‘*’ f(i, j) = f(i, j-1);

初始状态: f(-1, -1) = true;
如果p[j] = ‘*’ f(-1, j) = f(-1, j-1) = f(-1, j-2) //注意不要忘记;
复杂度为len(p) = m, len(s) = n;
空间复杂度2m;
时间复杂度m*n;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值