zoukankan      html  css  js  c++  java
  • 剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

    递归与循环

    递归:在一个函数的内部调用这个函数。

    本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算)

    优点:简洁,易于实现。

    缺点:时间和空间消耗严重,如果递归调用的层级太多,就会超出栈容量。

    循环:通过设置计算的初始值及终止条件,在一个范围内重复运算。

    斐波拉契数列

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

    第一种解法:用递归的算法:

    long long Fabonacci(unsigned int n)
    {
    	if(n<=0)
    		return 0;
    	if(n==1)
    		return 1;
    	return Fabonacci(n-1)+Fabonacci(n-2);
    }
    

     当n=10的时候的调用图如下:

    从上图我们可以看到递归的时候,有很多数都被重复计算了,对性能带来极其负面的影响,改算法的时间复杂度为n的指数次方。

    第二种解法:用循环(时间复杂度为O(n))

    #include <iostream>
    using namespace std;
    long long Fabonacci(unsigned int n)
    {
        int arrary[2]={0,1};
        long long FabN;
    
        if(n<2)
            FabN=arrary[n];
        long long FabOne=1;
        long long FabTwo=0;
        for(unsigned int i=2;i<=n;++i)
        {
            FabN=FabOne+FabTwo;
            FabTwo=FabOne;
            FabOne=FabN;
        }
        return FabN;
    }
    void main()
    {
     long long n=Fabonacci(15);
     cout<<n<<endl;
    
    }

    java代码:

    public class Fabonacci {
          //斐波拉契数列的非递归的实现,用循环。时间复杂度为O(n)
        public int fabonacci(int n){
            int[] a={0,1};
            if(n<2)
                return a[n];
            int FabOne=0;
            int FabTwo=1;
            int FabN=0;
            for(int i=2;i<=n;i++){
                FabN=FabOne+FabTwo;
                FabOne=FabTwo;
                FabTwo=FabN;
            }
            return FabN;
        }
        //斐波拉契数列的递归写法
        public long fabonacci1(long n){
            long fabN=0;
            if(n<=0)
              fabN=0;
            else if(n==1)
              fabN=1;
            else
                fabN=fabonacci1(n-1)+fabonacci1(n-2);
            return fabN;
        }
        public static void main(String[] args){
            Fabonacci fab=new Fabonacci();
            int f=fab.fabonacci(5);
            long f1=fab.fabonacci1(5);
            System.out.println(f+" "+f1);
        }
    }


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

    思路:当只有一级台阶的时候,青蛙的跳法也只有一种。当有两级台阶的时候,青蛙的跳法有两种(一是:一下跳两级台阶,二是:一级一级的跳)。当有n级台阶的时候,青蛙在第一次起跳的时候只跳了一级台阶,则还剩下n-1级台阶的跳法,如果在第一次起跳的时候跳了两级台阶,则还剩下n-2级台阶的跳法。整个题目正好是一个斐波拉契数列。公式如下:

     题目三:矩阵的覆盖,用八个2*1的小矩阵去覆盖一个2*8的大矩阵。如下图所示:

    第一个小矩阵可以有两种覆盖方法横着,那么此时,必须由第二个小矩阵也横着,剩下2*6的大矩阵;竖着,那么还剩下2*7的大矩阵需要覆盖。因此可得:f(8)=f(6)+f(7).

    公式同上第二题。

  • 相关阅读:
    hdu 3666 差分约束系统
    hdu 1198农田灌溉
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    高等微積分(高木貞治) 1.4節 例2
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    解析函數論 Page 29 命題(2) 函數模的有界性
    高等微積分(高木貞治) 1.4節 例2
    解析函數論 Page 29 命題(1) 有界閉集上的一致連續性
    解析函數論 Page 29 命題(3) 模的下界的可達性
    解析函數論 Page 29 命題(2) 函數模的有界性
  • 原文地址:https://www.cnblogs.com/hupp/p/4519198.html
Copyright © 2011-2022 走看看