第十題:斐波那契數列

lightmare625發表於2018-07-18

大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項(從0開始,第0項為0)。

n<=39

 

難度:⭐⭐⭐⭐

關鍵:不能用遞迴,時間複雜度會以n的指數方式增長,導致stackoverflow。要用迴圈,為了計算量不大,要自下而上的迴圈,將運算結果存在中間變數中,這樣就是O(n),以一定的空間代價避免代價更大的重複計算的棧空間浪費。

思路:從2開始。f(2)=f(1)+f(0)...one=1,two=0,for(;;){result=one+two;one=result;two=one}

其他:青蛙跳臺階(普通+變態版),矩形覆蓋。運用了數學建模的分類思想。

關於動態規劃三個條件:最優子結構、無後效性、子問題重疊。

 

我的。

class Solution {
public:
    int Fibonacci(int n) {
        //n<2時
        
        if(n<0) throw exception();
        else if(n<2) return n;
        else
        {
            int result=0;
            int first=1;
            int second=0; 
            for(int i=1;i<n;i++)
            {
                result=first+second;
                second=first;
                first=result;
            }
            return result;
        }

    }
};

 c++動態規劃版

class Solution {
public:
    int Fibonacci(int n) {
        int f = 0, g = 1;
        while(n--) {
            g += f;
            f = g - f;
        }
        return f;
    }
};

 

python 。以陣列的方式。

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        res=[0,1,1,2]
        while len(res)<=n:
            res.append(res[-1]+res[-2])
        return res[n]

 其他題目 

青蛙跳臺階

class Solution {
public:
    int jumpFloor(int number) {
        if(number<=0) throw exception();
        if(number<=2)
            return number;
        else
        {
            //f(3)=f(2)+f(1)
            int one=2;
            int two=1;
            int result=3;
            for(int i=2;i<number;i++)
            {
                result=one+two;
                two=one;
                one=result;
            }
            return result;
        }
        
    }
};

python

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, n):
        # write code here
        res=[1,1,2]
        while len(res)<=n:
            res.append(res[-1]+res[-2])
        return res[n]

青蛙跳臺階變態版

一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

關於本題,前提是n個臺階會有一次n階的跳法。分析如下:

f(1) = 1

f(2) = f(2-1) + f(2-2)         //f(2-2) 表示2階一次跳2階的次數。

f(3) = f(3-1) + f(3-2) + f(3-3) 

...

f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n) 

 

說明: 

1)這裡的f(n) 代表的是n個臺階有一次1,2,...n階的 跳法數。

2)n = 1時,只有1種跳法,f(1) = 1

3) n = 2時,會有兩個跳得方式,一次1階或者2階,這回歸到了問題(1) ,f(2) = f(2-1) + f(2-2) 

4) n = 3時,會有三種跳得方式,1階、2階、3階,

    那麼就是第一次跳出1階後面剩下:f(3-1);第一次跳出2階,剩下f(3-2);第一次3階,那麼剩下f(3-3)

    因此結論是f(3) = f(3-1)+f(3-2)+f(3-3)

5) n = n時,會有n中跳的方式,1階、2階...n階,得出結論:

    f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

    

6) 由以上已經是一種結論,但是為了簡單,我們可以繼續簡化:

    f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

    f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

    可以得出:

    f(n) = 2*f(n-1)

    

7) 得出最終結論,在n階臺階,一次有1、2、...n階的跳的方式時,總得跳法為:

              | 1       ,(n=0 ) 

f(n) =     | 1       ,(n=1 )

              | 2*f(n-1),(n>=2)

class Solution {
public:
    int jumpFloorII(int number) {
        // f(n) = 2*f(n-1)
        if (number <= 0) {
                return -1;
            } else if (number == 1) {
                return 1;
            } else {
                return 2 * jumpFloorII(number - 1);
            }
    }
};

python

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        a=[1,2,4,8]
        while(len(a)<number):
            a.append(a[-1]*2)
        return a[number-1]

 

 

小矩形覆蓋大矩形

class Solution {
public:
    int rectCover(int number) {
        if(number<=2) return number;
        else
        {
            //f(3)=f(2)+f(1)
            //f(4)=f(3)+f(2)
            int one=2;
            int two=1;
            int result=3;
            for(int i=2;i<number;i++)//3
            {
                result=one+two;
                two=one;
                one=result;
            }
            return result;
        }
    }
};

python

# -*- coding:utf-8 -*-
class Solution:
    def rectCover(self, number):
        # write code here
        a=[0,1,2,3]
        while(len(a)<=number):
            a.append(a[-1]+a[-2])
        return a[number]

 

相關文章