LeetCode10:正则表达式匹配问题

场景:

最近上LeetCode刷题,碰到正则表达式匹配问题,描述如下:


分析:

刷算法题本人一直遵循Kent Beck的三部曲:Make it work->Make it right->Make it fast 。

首先,随机选取一个测试用例进行匹配模拟操作,你会发现你会很自然地采用逐个字符匹配的方式进行匹配;这就意味着对于该问题的求解实际上可以划分为若干小问题的求解,那么到这就会想到可以采用递归的方式来解决该问题。

#region 解决方案一:递归

递归的基本思想在于把规模大的问题转化为规模较小的相似的子问题来解决,根据子问题规模大小又分为两种策略:线性递归(减而治之)和二分递归(分而治之);

不过多解释,上俩图来描述(有兴趣可以去搜索邓公的数据结构课程):

减治:

分治:

对于本例,采用线性递归的方式来求解:

从递归的角度看,为求解 IsMatch(s,p),需

递归求解规模为 length-1 的问题 IsMatch(s,p-1)

递归基:IsMatch(s[0],p[0])

总体思路如下:

——边界控制:考虑字符模式p和字符串s为空的情况

 if (String.IsNullOrEmpty(p))
 {
                return String.IsNullOrEmpty(s);
 }

——递归基:考虑字符模式长度为1和带有‘*’两种情形

if (p.Length == 1)
{
    return s.Length == 1 && (s[0] == p[0] || p[0] == '.');
}
if (p[1] != '*')
{
    if (String.IsNullOrEmpty(s))
    {
        return false;
    }
    return (s[0] == p[0] || p[0] == '.') && IsMatch(s.Substring(1), p.Substring(1));
}
while (!String.IsNullOrEmpty(s) && (s[0] == p[0] || p[0] == '.'))
{
    if (IsMatch(s, p.Substring(2)))
    {
        return true;
    }
    s = s.Substring(1);
}

——递归关系

return IsMatch(s, p.Substring(2));

#endregion 递归

总结:

通过递归的方式往往只能make work和right,但是要想高效,对于规模较大的问题递归往往不适用。比如,对于常见的斐波那契数列问题,使用直接递归方式只能快速计算40+层,越往后时间消耗越长,效率非常低。直接递归可能出现大量的重复子问题(斐波那契数列计算低效的原因),存在大量重复的计算,严重影响性能。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值