斐波那契數列和青蛙跳問題

原文鏈接:http://blog.csdn.net/qq_22329521/article/details/52967839

遞歸的顯著缺點

遞歸由于調用自身,而函數調用是有時間和空間的消耗的:每一次函數調用,都需要在內存棧中分配內存空間以保存參數、返回地址及臨時變量,而且往棧里壓入數據和彈出數據都需要時間。
另外,遞歸中有可能很多計算都是重復的,從而對性能帶來很大的負面影響。遞歸的本質是把一個問題分解成兩個或者多個小問題。如果多個小問題存在互相重疊的部分,那么久存在重復的計算。
斐波那契數列
效率最低的解法

//遞歸調用
    long fibonacci(int n){
        if(n<=0){
            return 0;
        }
        if (n==1){
            return 1;
        }
        return fibonacci(n-1)+fibonacci(n-2);
    }

enter image description here

樹中有多個結點是重復的,而且重復的結點數會隨著n的增加而急劇增加,這意味著隨著n增加。用遞歸方法計算的時間復雜度是以n的指數的方式遞增的
改進的方式,只要避免重復計算,將得到的數列中間值保存起來,下次要計算查找一下
更簡單的方式是從下往上走,計算f(0)和f(1)的f(2)以此計算

 public static int fibonaci(int n) {
        int result[ 2]={
            0, 1
        } ;
        if (n < 2) return result[n];
        long fibNMinusOne=1;
        long fibNMinuesTwo=2;
        long fibN=0;
        for(int i =2;i<=n;i++){
            fibN = fibNMinusOne+fibNMinuesTwo;
            fibNMinuesTwo = fibNMinusOne;
            fibNMinusOne =fibN;
        }
        return fibN;
    }

青蛙跳題目(擴展)
一只青蛙一次可以跳上一個臺階,也可以跳上2個臺階,求青蛙跳上一個n級臺階共有多少總跳法
思路:如果只有1級臺階,顯然只有一種跳法,如果兩個臺階,就來有種跳法
一般情況下,我們把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)

青蛙跳擴展2
如果一只青蛙一次可以跳上1級臺階,也可以跳上2級臺階。。。它也可以跳上n級臺階,此時青蛙跳上一個n級臺階共有集中跳法,用數學的歸納法可以證明是f(n)=2^{(n-1)}

格子覆蓋問題(擴展)
我們可以用2x1 的小矩形橫著或者豎著去覆蓋更大的矩形如8個2x1 的小矩形無重疊的覆蓋一個2x8的大矩形,共有幾種方法


這里寫圖片描述

思路:我們先把2x8的覆蓋方法記為f(8)用第一個1x2小矩形去覆蓋大矩形的最左邊兩個選擇,豎著或者橫著放,當豎著放,右邊還剩下2x7的區域,它的覆蓋方法即為f(7)。然后考慮橫著放的情況。當1x2的小矩形橫著放在左上角的時候,左下角必須和橫著放一個1x2的小矩形,而在右邊還剩下2x6的區域,這種情形下的覆蓋方法記為f(6),因此f(8)=f(7)+f(6)也是個斐波那契數列

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容