【剑指offer】:Fibonacci数列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hansionz/article/details/82228109
0.什么是Fibonacci数列?

例如:

0 1 1 2 3 5 8 13.....

它被定义为:
这里写图片描述

1.题目

现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)

2.解题思路
  • 递归
long long Fibonacci(unsigned int n)
{
    if (n <= 0)
    {
        return 0;
    }
    if (n == 1)
    {
        return 1;
    }
    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

也可以像下边这么写:

long long Fibonacci(unsigned int n)
{
    return n < 2 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
}

但是上边的代码其实在一些场景是有问题的,对于比较小的数字计算机可以很快的计算出它的结果,但是对于稍微大一些的数字,计算机计算出结果需要很长时间。而对于更大的数字,程序则会崩溃,提示说栈溢出。这是为什么呢?由于递归是函数调用自身的过程,我们知道每一次函数调用的过程都需要在栈中分配空间以保存函数参数、返回地址、临时变量等等。另外,每次向栈中压入或者弹出数据都需要时间的消耗,栈空间也是有限的,如果调用太多,就会有栈溢出的问题。当然,对于递归求Fibonacci数列还有一个问题,就是存在重复求值的过程,这样会很大的影响效率,下边可以分析一下求Fibonacci数列函数的调用关系:

这里写图片描述

因此,我们应该考虑用循环解决上边的重复性计算和效率、栈溢出的问题

  • 非递归
long long Fibonacci(unsigned int n)
{
    int FibOne = 0, FibTwo = 1, FibN = n;
    int i = 2;
    for (; i <= n; i++)
    {
        FibN = FibOne + FibTwo;
        FibOne = FibTwo;
        FibTwo = FibN;
    }
    return FibN;
}

猜你喜欢

转载自blog.csdn.net/hansionz/article/details/82228109