递归及递归的简单运用之4种方法解斐波那契数列

什么是递归?
若一个对象部分的包含自己或用它自己给自己定义,那么我们说这个对象是递归的;若一个过程直接或间接的调用自己,那么这个过程是递归的。
递归的思想是把问题分解为规模更小具有与原问题相同解法的子问题,因此可以让我们思考的方式更加简单,程序也更加简练。不过就递归函数而言递归增加了压栈开销,因此空间复杂度比较高。
递归条件:
(1)、减小问题规模,并使子问题与原问题有相同解法。
(2)、设置出口,如果没有出口那么程序会一直递归下去。
递归的简单运用
斐波那契数列是递归问题中非常典型的一个了,我们常用循环的方式解斐波那契数列,循环解法:

long Fibonacci2(size_t N)         //时间复杂度O(n),空间复杂度O(1)
{
    long first = 1;
    long second = 1;
    long sum = 0;
    if (N < 3)
        return 1;
    else
    {
        for (size_t i = 3; i <= N; i++)
        {
            sum = first + second;
            first = second;
            second = sum;
        }
        return sum;
    }
}

这种解法是比较高效的一种解法。
现在来看递归解法:

long Fibonacci1(size_t N)        //时间复杂度O(2^N),空间复杂度O(n)
{
    if (N < 3)
        return 1;
    else
        return Fibonacci1(N - 1) + Fibonacci1(N - 2);
}

这种解法思维方式非常简单,但是时间复杂度特别高,一般不建议采用这种方法。
我们来看一种比较高效的递归解法:

long Fibonacci3(long first, long second, size_t N)  //时间复杂度O(n),空间复杂度O(1)
{
    if (N < 3)
        return second;
    else
        return Fibonacci3(second, first + second, N - 1);
}

如果说前一种递归解法是由后向前计算,那么这种解法就是由前向后计算了,这种递归方式属于尾递归,因此在进行递归时函数只会使用第一次压栈所开辟的栈空间,在一个栈空间内循环,而不会开辟别的栈空间,所以这种方式时间复杂度为O(N),空间复杂度为O(1),是一种非常高效的递归方式。
除此之外还有一种递归解法:

long *Fibonacci4(size_t N)             //时间复杂度O(n),空间复杂度O(n)
{
    long *array = new long[N + 1];
    if (N == 0)
        return NULL;
    array[0] = 0;
    array[1] = 1;
    for (size_t i = 2; i <= N; i++)
    {
        array[i] = array[i - 1] + array[i - 2];
    }
    return array;
}

这种递归解法并不比上一种方式高效,之所以写出来是因为这种递归方式是在一个代码块内递归,而不是上面那种函数的递归。
斐波那契数列解法非常多,在此仅给出4种解法。希望各位大神斧正。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值