剑指offer--面试题9

题目一:求斐波那契数列第n项

自己所写代码如下:

#include "stdafx.h"
#include<iostream>

long Fibonacci(unsigned int N)
{
    long F0 = 0;
    long F1 = 1;
    if(N == 0)
        return F0;
    else if(N == 1)
        return F1;
    else
    {
        int n = 2;
        while(n <= N)
        {
            F0 = F0 + F1;
            F1 = F0 + F1;
            n += 2;
        }
        return (N % 2 == 0)? F0 : F1;
    }
}
int main()
{
    int N = 10;
    for(int i=0; i<=N; i++)
    {
        long FValue = Fibonacci(i);
        std::cout<<FValue<<std::endl;
    }
    return 0;
}

虽然知道可以用递归实现,但实际写代码却有些生疏,关键是对递归不是很熟练。。。

 参考作者代码,基于递归的实现如下:

long Fibonacci(unsigned int n)
{
    int results[2] = {0,1};
    //递归终止条件
    if(n < 2)
        return results[n];
    
    return Fibonacci(n-1) + Fibonacci(n-2);

}

递归代码相当简洁!但正如书中所说,用递归求解斐波那契数列的第n项,会由于有很多重复的子问题求解,比如求解f(10)时,会求解两次f(8),因而造成计算复杂度随着n的增大而急剧增加!因此,该题用递归解并不是一种好的选择!时间复杂度:O(2_^n),即以n为指数的增长。

作者所写基于循环的实现如下:(很规范)

 
 
long Fibonacci(unsigned int n)
{
    int results[2] = {0,1};
    
    if(n < 2)
        return results[n];

    long Fib_0 = results[0];
    long Fib_1 = results[1];
    long Fib_i;
    for(int i=2; i <= n; i++)
    {
        Fib_i = Fib_0 + Fib_1;
        Fib_0 = Fib_1;
        Fib_1 = Fib_i;
    }
    
    return Fib_i;
}
 
 
和自己所写的代码,思想一致!时间复杂度:O(n)。

该题时间复杂度可以达到O(logn),只做了解了。

 

 题目二:(关于斐波那契数列的应用)

青蛙跳台阶,每次只能跳1个台阶或者2个台阶,则问青蛙若要跳n个台阶共有多少种跳法?

分析:该题的思路不太好想。。。

首先要想到以n为变量,n个台阶的跳法共有f(n)种,那么:

分析一:到第n-1阶后,再跳一步即到第n阶,此时的跳法为f(n-1);

           到第n-2阶后,再跳一个两步或者连续跳一步即可到第n阶,但此时注意到后者包含在上一步中,所以此时的跳法为f(n-2),而非2*f(n-2)。

分析二:以开始跳为分界点更好些。

          第一跳若为跳一步,则剩下的n-1台阶的跳法为f(n-1);

          第一跳若为跳一个两步,则剩下的n-2台阶的跳法为f(n-2);

          避免 对分析一中特殊情况的忽略。

综上,n个台阶的跳法f(n)=f(n-1)+f(n-2)为斐波那契数列!!!

 

转载于:https://www.cnblogs.com/hello-yz/p/3248169.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值