斐波那契数列及青蛙跳台阶问题

题目1:

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

斐波那契(Fibonacci)数列定义例如以下:

f(n)=?????0,1,f(n?1)+f(n?2),n=0n=1n>2

效率非常低的解法:

  1. 递归解法(效率非常低)
long long Fibonacci_Solution1(unsigned int n)
{
  if(n <= 0)
     return 0;

  if(n == 1)
     return 1;

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

2 循环解法:改进的算法:从下往上计算。首先依据f(0)和f(1)算出f(2)。再依据f(1)和f(2)算出f(3)。。。。。依此类推就能够算出第n项了。

非常easy理解。这样的思路的时间复杂度是o(n)。实现代码例如以下:

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

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

        fibMinusTwo = fibMinusOne;
        fibMinusOne = fibN;
    }

    return fibN;
}

题目2:

 一仅仅青蛙一次能够跳上1级台阶,也能够跳上2级。求该青蛙跳上一个n级的台阶总共同拥有多少种跳法。

能够把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)。分析到这里,不难看出这实际上就是斐波那契数列了。

与斐波那契数列不同的是,其初始值定义稍有不同。

当n=1时,仅仅能跳一级台阶,一种跳法

当n=2时。一次跳一级或两级,两种跳法

所以。关于青蛙跳台阶的定义例如以下:

f(n)=?????1,2,f(n?1)+f(n?2),n=1n=2n>2

  1. 非递归写法
long long FrogJump12Step(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }

    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    int frogNMinusOne = 2;//f(n-1)=2
    int frogNMinusTwo = 1;//f(n-2)=1
    int frogN = 0;
    for (unsigned int i = 3; i <= n;++i)
    {
        frogN = frogNMinusOne + frogNMinusTwo;
        frogNMinusTwo = frogNMinusOne;
        frogNMinusOne = frogN;
    }
    return frogN;
}
  1. 递归解法
long long FrogJump12StepRecursive(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    return FrogJump12StepRecursive(n - 1) + FrogJump12StepRecursive(n - 2);
}

题目3:

  一仅仅青蛙一次能够跳上1级台阶,也能够跳上2级。

。

。

。。它也能够跳上n级,此时该青蛙跳上一个n级的台阶总共同拥有多少种跳法?

用数学归纳法能够证明:f(n)=2n?1.

递归式证明:

当n = 1 时, 仅仅有一种跳法,即1阶跳:Fib(1) = 1;

当n = 2 时。 有两种跳的方式,一阶跳和二阶跳:Fib(2) = Fib(1) + Fib(0) = 2;

当n = 3 时。有三种跳的方式,第一次跳出一阶后。后面还有Fib(3-1)中跳法。 第一次跳出二阶后,后面还有Fib(3-2)中跳法;第一次跳出三阶后,后面还有Fib(3-3)中跳法

Fib(3) = Fib(2) + Fib(1)+Fib(0)=4;

当n = n 时。共同拥有n种跳的方式,第一次跳出一阶后。后面还有Fib(n-1)中跳法; 第一次跳出二阶后。后面还有Fib(n-2)中跳法……………………..第一次跳出n阶后, 后面还有 Fib(n-n)中跳法.

Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+……….+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-1)

又由于Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-2)

两式相减得:Fib(n)-Fib(n-1)=Fib(n-1)

=====》 Fib(n) = 2*Fib(n-1) n >= 2

递归等式例如以下:

f(n)=?????1,2,2?f(n?1),n=1n=2n>2

所以:f(n)=2?f(n?1)=2?2(n?2)....=2n?1?f(0)=2n?1

  1. 非递归解法:
long long FrogJump12nStep(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }
    else if (n == 1)
        return 1;
    else
    {
        long long  fn1 = 1;
        long long fn = 0;
        for (int i = 2; i <= n;++i)
        {
            fn = 2 * fn1;
            fn1 = fn;
        }
        return fn;
    }
}
  1. 递归解法
long long FrogJump12nStepRecursive(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }
    else if (n == 1)
        return 1;
    else if (n == 2)
        return 2;
    else
        return 2 * FrogJump12nStepRecursive(n - 1);
}

题目4:

小矩形覆盖大矩形,用2*1的小矩形横着或竖着去覆盖各大矩形。

思路:设题解为f(n),

第一步:若第一块矩形竖着放,后边还有n-1个2*1矩形,即此种情况下,有f(n-1)种覆盖方法。
第二部:若第一块横着放。后边还有n-2个2*1矩形,此种情况下,有f(n-2)种覆盖方法。

第三部:可得 f(n)=f(n-1)+f(n-2)

可知,此题能够转化为其斐波那契数列第n项的值。

时间: 2024-11-14 09:56:43

斐波那契数列及青蛙跳台阶问题的相关文章

剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调用的层级太多,就会超出栈容量. 循环:通过设置计算的初始值及终止条件,在一个范围内重复运算. 斐波拉契数列 题目一:写一个函数,输入n,求斐波拉契(Fibonacci)数列的第n项,定义如下: 第一种解法:用递归的算法: long long Fabonacci(unsigned int n) { i

青蛙跳台阶问题-斐波拉契数列

题目1:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级.求总共有多少种跳法 首先我们考虑最简单的情况,加入只有1级台阶,那显然只有一种跳法,如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级:另外一种就是一次跳2级 现在我们来讨论一般情况.我们把n级台阶时的跳法看成是n的函数,记为f(n).当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1):另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的

刷题9 斐波那契数列及跳台阶问题

斐波那契数列问题描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.  n<=39 关于斐波那契数列, 定义是这样的: 因为递归太浪费空间, 所以采用循环: 1 class Solution { 2 public: 3 int Fibonacci(int n) { 4 if(n < 2) 5 return n; 6 int first = 0; 7 int second = 1; 8 int sum = -1; 9 for(int i = 0; i < n

斐波那契数列与跳台阶问题以及变态跳台阶

1.跳台阶问题:(其实就是很纯粹的斐波那契数列问题)比较倾向于找规律的解法,f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5,  可以总结出f(n) = f(n-1) + f(n-2)的规律,但是为什么会出现这样的规律呢?假设现在6个台阶,我们可以从第5跳一步到6,这样的话有多少种方案跳到5就有多少种方案跳到6,另外我们也可以从4跳两步跳到6,跳到4有多少种方案的话,就有多少种方案跳到6,其他的不能从3跳到6什么的啦,所以最后就是f(6) = f(5) + f(4):

07 斐波那契数列 08 跳台阶 两个题的解答相似

官方正规的数学界的斐波那契数列的定义: 波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1.1.2.3.5.8.13.21.34.……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用. 是以1

剑指offer(10)—— 斐波那契数列以及跳台阶问题

总结 2^(n-1)可以用位移操作进行: 1<< (n-1) 如果递归不好思考的话,可以找规律,代码很简单 斐波那契数列(10) 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 public class Solution { public int Fibonacci(int n) { // 先判断n必须在范围内取值 if(n > 39 && n <= 0) return 0; // 为1直接返

斐波那契数列-跳台阶

题目描述一 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). def Fibonacci(self, n): res = [0, 1] while len(res) <= n: res.append(res[-1]+res[-2]) return res[n] 题目描述二 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). # -*- coding:utf-8 -*- cla

【剑指offer】斐波那契数列

题目1描述: 写一个函数,输入n,求斐波那契数列的第n项.斐波那契数列的定义如下: f(n) = 0 (n = 0);  f(n) = 1 (n = 1);  f(n) = f(n-1)+f(n-2) (n > 1); 分析描述: 在大多数的C语言教科书中,一般会用递归求斐波那契数列.代码如下: long long Fibonacci(unsigned int n) { if(n <= 0) return 0; if(n <= 1) return 1; return Fibonacci(

斐波拉契数列的计算方法

面试题9.斐波拉契数列 题目: 输入整数n,求斐波拉契数列第n个数. 思路: 一.递归式算法: 利用f(n) = f(n-1) + f(n-2)的特性来进行递归,代码如下: 代码: long long Fib(unsigned int n) { if(n<=0) return 0; if(n==1) return 1; return Fib(n-1) + Fib(n-2); } 缺陷: 当n比较大时递归非常慢,因为递归过程中存在很多重复计算. 二.改进思路: 应该采用非递归算法,保存之前的计算结