劍指offer面試題9 斐波那契數列及青蛙跳臺階問題

頭像是我偶像發表於2017-05-22

一、要求時間複雜度為O(N)實現斐波那契數列

1.1 題目

大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。(n<=39)

1.2 解析

  1. 效率低下的解法:遞迴法
    遞迴演算法裡面包含了大量的重複計算,所以效率低,遞迴演算法時間複雜度為:O(2^ (N/2))<=T(N)<=O(2^ N)。

  2. 時間複雜度為O(N)的解法
    簡單的辦法是從下往上計算,首先根據f(0)和f(1)計算f(2),再根據小的計算魘,依此類推出f(n)。

1.3 程式碼實現

//時間複雜度為O(N)的解法
public class Solution {
    public int Fibonacci(int n) {
        int[] array = {0,1};
        if(n<2){
            return array[n];
        }
        int result = 0;
        for (int i = 2; i <= n; i++) {
            result = array[0]+array[1];
            array[0] = array[1];
            array[1] = result;
        }
        return result;
    }
}

二、青蛙跳臺階

2.1 題目

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

2.2 解析

來源:牛客網

前提只有 一次 1階或者2階的跳法。
1. 如果兩種跳法,1階或者2階,那麼假定第一次跳的是一階,那麼剩下的是n-1個臺階,跳法是f(n-1);
2. 假定第一次跳的是2階,那麼剩下的是n-2個臺階,跳法是f(n-2)
3. 由a\b假設可以得出總跳法為: f(n) = f(n-1) + f(n-2) 3. 然後通過實際的情況可以得出:只有一階的時候 f(1) = 1 ,只有兩階的時候可以有 f(2) = 2
4. 可以發現最終得出的是一個斐波那契數列:

2.3 程式碼實現

public class Solution {
    public int JumpFloor(int target) {
        int f = 0;
        int g = 1;
        while(target-->0){
            g = g+f;
            f = g-f;
        }
        return g;
    }
}

三、變態跳臺階

3.1 題目

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

3.2 解析

來源:牛客網

關於本題,前提是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(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)

    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)=4*f(n-2)=…=2^(n-1) *f(1)=2^(n-1)

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

          | 1  ,(n=0 )
          f(n) = | 1  ,(n=1 )
     | 2^(n-1),(n>=2)
    

3.3 程式碼實現

public class Solution {
    public int JumpFloorII(int target) {
        return (int) Math.pow(2, target-1);
    }
}

相關文章