剑指Offer面试题:7.斐波那契数列

本文介绍了斐波那契数列的两种计算方法:一种是递归方式,尽管直观但效率低下;另一种是非递归方式,通过迭代计算提高了效率至O(n)。文章对比分析了两种方法,并给出了具体的C++实现代码。

一 题目:斐波那契数列

题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:

二 效率很低的解法

  很多C/C++/C#/Java语言教科书在讲述递归函数的时候,大多都会用Fibonacci作为例子,因此我们会对这种解法烂熟于心

#include "stdio.h"
#include <iostream>
using namespace std;

int Fibs(int n)
{
    if (0 == n)
    {
        return 0;
    }
    else if (1 == n)
    {
        return 1;
    }
   return Fibs(n-1) + Fibs(n-2);
}

void main()
{
    cout << "斐波那契数列:" << endl;
    cout <<Fibs(0)<<" ";
    cout <<Fibs(1)<<" ";
    cout <<Fibs(2)<<" ";
    cout <<Fibs(3)<<" ";
    cout <<Fibs(4)<<" ";
    cout <<Fibs(5)<<" ";
    cout <<Fibs(6)<<" ";
    cout <<Fibs(7)<<" ";
    cout <<Fibs(8)<<" " << endl;
    return;
}

  上述递归的解法有很严重的效率问题,通过求解第10项的调用过程图来分析:

  

  从上图中不难发现:在这棵树中有很多结点是重复的,而且重复的结点数会随着n的增大而急剧增加,这意味计算量会随着n的增大而急剧增大。事实上,用递归方法计算的时间复杂度是以n的指数的方式递增的

三 时间复杂度为O(n)的解法

  改进的方法并不复杂。上述递归代码之所以慢是因为重复的计算太多,我们只要想办法避免重复计算就行了。这里的办法是从下往上计算,首先根据f(0)和f(1)算出f(2),再根据f(1)和f(2)算出f(3)……依此类推就可以算出第n项了。很容易理解,这种思路的时间复杂度是O(n)

#include "stdio.h"
#include <iostream>
using namespace std;

int Fibs(int n)
{
    int nFibs = 0;
    if (0 == n)
    {
        return 0;
    }
    else if(1 == n)
    {
        return 1;
    }
    int nSubOne = 1;  // Fibs(n-1)
    int nSubTwo = 0;  // Fibs(n-2)
    for (int i = 2; i <= n; i ++)
    {
        nFibs = nSubOne + nSubTwo;
        nSubTwo = nSubOne;
        nSubOne = nFibs;
    }

    return nFibs;
}

void main()
{
    cout << "斐波那契数列:" << endl;
    cout <<Fibs(0)<<" ";
    cout <<Fibs(1)<<" ";
    cout <<Fibs(2)<<" ";
    cout <<Fibs(3)<<" ";
    cout <<Fibs(4)<<" ";
    cout <<Fibs(5)<<" ";
    cout <<Fibs(6)<<" ";
    cout <<Fibs(7)<<" ";
    cout <<Fibs(8)<<" " << endl;
    return;
}

转载于:https://www.cnblogs.com/xiaobingqianrui/p/8833066.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值