剑指Offer系列---(12)斐波那契数列

本文介绍了如何解决剑指Offer中关于斐波那契数列的面试题,详细分析了青蛙跳台阶问题,分为两种情况讨论,揭示了问题与斐波那契数列的关系。并提供了两种不同场景下的源代码实现。
摘要由CSDN通过智能技术生成

1.题目描述:

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


2.源代码:

//  Copyright (c) 2015年 skewrain. All rights reserved.

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

//递归,效率很低的解法,时间复杂度是以n的指数的方式递增的。
long long Fibonacci1(unsigned int n)
{
    if(n <= 0)
        return 0;
    if(n == 1)
        return 1;
    
    return Fibonacci1(n-1) + Fibonacci1(n-2);
}

//简单的迭代方法,从下往上计算,时间复杂度为O(n)。
long long Fibonacci2(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(int argc,char *argv[]){

    int n1,n2;
    cout<<"请输入n1:";
    cin>>n1;
    cout<<"F("<<n1<<")的值为:"<<Fibonacci1(n1)<<endl;
    
    cout<<"请输入n2:";
    cin>>n2;
    cout<<"F("<<n2<<")的值为:"<<Fibonacci2(n2)<<endl;
    
    return 0;
}

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

分析:
1)首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳得方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。
2)接着我们再来讨论一般情况。如果把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。我们可以看出是斐波那契数列了。

源代码:

long long jumpFloorI(int number)
{
    if(number<=1)
        return 1;
    if(number==2)
        return 2;
    long long result[100];
    result[1] = 1;
    result[2] = 2;
    for (int i = 3; i<number+1; i++) {
        result[i] = result[i-1]+result[i-2];
    }
    return result[number];
}

B.【疯狂跳台阶】一只青蛙一次可以跳上1级台阶,也可以跳上2级......它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

分析:
假设现在n=10,方法记为f(10),如果第一下跳了1级,那么剩下的方法为f(9),如果第一下跳了2级,那么剩下的方法是f(8),……,如果第一下跳了9级,那么剩下的方法是f(1),如果第一下就直接跳上10级,那么就只有一种方法。
因此,f(10)=f(9)+f(8)+f(7)+f(6)+f(5)+f(4)+f(3)+f(2)+f(1)+1;
刚开始f(1)=1,f(2)=2。

源代码:

long long jumpFloorII(int number)
{
    if(number<=1)
        return 1;
    if(number==2)
        return 2;
    long long result[100];
    result[1] = 1;
    result[2] = 3;
    for (int i = 3; i<=number; i++)
    {
        {
            for(int j = 1;j<i;j++)
                result[i] += result[j];
        }
        result[i] += 1;
    }
    return result[number];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值