【剑指offer】7-斐波那契数列

本文系《剑指offer》的刷题记录,通过牛客网在线平台测试通过。
在线测试平台:牛客网
编程资料获取:CodeLab

1-Description

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39

2-Solution

1-问题分析
我们知道Fibonacci数列的定义可以用如下的公式表示:
F i b ( n ) = { 0 , n = 0 1 , n =1 F i b ( n − 1 ) + F i b ( n − 2 ) , n&gt;1 Fib(n) = \begin{cases}0,&amp;\text{n = 0} \\1,&amp;\text{n =1} \\Fib(n-1) + Fib(n-2),&amp;\text{n&gt;1} \end{cases} Fib(n)=0,1,Fib(n1)+Fib(n2),n = 0n =1n>1
当然可以很快的将公式转为如下的代码:

class Solution {
public:
    int Fibonacci(int n) {
        if(n == 0) return 0;
        if(n == 1) return 1;
        return Fibonacci(n-1) + Fibonacci(n-2);
    }
};

但是这样的递归解法在当n很大的时候,会因为计算超时而不能被ac
递归版的fib()低效的根源在于各递归实例均被重复调用,下图以计算fib(5)为例(其中数字均表示计算该数的斐波那契数,下同),可以看出来有非常多的重复调用

针对上述的递归所带来的超时问题可以采用2中方法进行解决:

  • 解决方法A(记忆:memoization):将已计算过实例的结果制表备查,避免重复调用
  • 解决方法B(动态规划:dynamic programingg)颠倒计算方向:由自顶而下递归变为自底而上迭代,可以用下图表示,需要注意的就是每一项的值都是依靠前两项的结果算出来的,所以自底上下迭代可以很方便的解决本问题

2-代码解决
依据上述分析,可以用下面的代码实现:

  • memoization方法
class Solution {
public:
   // const int N = 99;
    double memo[99];//将已经算得的结果制表备查
    int Fibonacci(int n) {
        if(n < 2) return n;
        if(memo[n]) return memo[n];//如果已经有计算结果,则直接返回表里的值
        else return memo[n] = Fibonacci(n-1) + Fibonacci(n-2);//常规递归算法
    }
};
  • dynamic programin
class Solution {
public:
    int Fibonacci(int n) {
        int f = 1;//相当于fib(-1)
        int g = 0;//fib(0)
        while( 0 < n--){
            g = g + f;//得到新的计算结果
            f = g - f;//f被赋作上一次的g
        }
        return g;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值