剑指offer--斐波那契数列

17 篇文章 0 订阅

记录来自《剑指offer》的算法题。

题目如下:

写一个函数,输入n,实现斐波那契数列的第n项。

斐波那契数列的定义如下:

f(n)=01f(n1)+f(n2)n=0n=1n>1

教科书上通常在介绍递归的时候都会使用斐波那契数列作为例子,然后给出下列解法:

long long Fibonacci(unsigned int n){
  if(n<=0)
    return 0;
  if(n == 1)
    return 1;

  return Fibonacci(n-1) + Fibonacci(n-2);
}

但这个算法在n的增大后会变得很慢,主要原因是重复的计算比较多,改进算法如下所示:

// 改进版本
long long FibonacciOptimz(unsigned int n){
    int result[2] = { 0, 1 };
    if (n < 2)
        return result[n];

    long long fibNMinusOne = 1;
    long long fibNMinusTwo = 0;
    long long fibN = 0;
    for (unsigned int i = 2; i <= n; i++){
        fibN = fibNMinusOne + fibNMinusTwo;

        fibNMinusTwo = fibNMinusOne;
        fibNMinusOne = fibN;
    }

    return fibN;
}
// 测试
int main(void){
    int n = 10;
    cout << "use Fibonacci(), n = " << n << ", result = " << Fibonacci(n) << endl;
    cout << "use FibonacciOptimz(), n = " << n << ", result = " << FibonacciOptimz(n) << endl;
    cout << "start to test:\n";
    int test[] = { 0, 1, 2, 3, 5, 10, 40, 50, 100 };
    for (int i = 0; i < 9; i++){
        int num = test[i];
        cout << "use FibonacciOptimz(), num = " << num << ", result = " << FibonacciOptimz(num) << endl;
    }

    system("pause");
    return 0;
}

这种算法的时间复杂度是 O(n) ,它采用循环的方法,每次循环的时候都保存中间值,并用于下次的计算。

对于斐波那契数列的应用,还有如下问题:

一只青蛙一次可以跳上一级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法。

这个问题也就是需要实现斐波那契数列。考虑最简单的情况,如果只有1级台阶,那显然只有一种跳法;如果有2级台阶,则有两种跳法,一次只跳1级和1次跳两级台阶。现在讨论一般情况,将n级台阶时的跳法看成是n的函数,记为 f(n) 。当 n>2 时,第一次跳的时候有两种选择,一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即 f(n1) ;另一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为 f(n2) 。因此n级台阶的不同跳法的总数 f(n)=f(n1)+f(n2) ,也就是斐波那契数列。

当然,如果上述问题的条件变成:青蛙一次可以跳上1级台阶,也可以跳上2级 它也可以跳上n级,问跳上n级台阶总共有多少种跳法。通过数学归纳法可以得到 f(n)=2n1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

spearhead_cai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值