1. 程式人生 > >劍指offer(7)

劍指offer(7)

開始 分享圖片 sha fibonacci 數列 cover image number n-1

  今天的幾道題目都是關於斐波那契數列的。

  題目1:

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

n<=39

  傳統的方法采用遞歸函數,這種方法也是我們在大學剛剛接觸遞歸函數時老師給的例子。但這種方法會消耗大量的時間和空間,所以在此我們不使用這種方法。

  思路大致如下圖

技術分享圖片

public class Solution {
    public int Fibonacci(int n) {
        int[] a ={0,1};
        
        if(n<2){
            return a[n];
        }
        
        int numberOne = 0;
        int numberTwo = 1;
        int numberResult = 0;
        
        for(int i=2; i<=n; i++){
            numberResult = numberOne + numberTwo;
            numberOne = numberTwo;
            numberTwo = numberResult;
        }
        
        return numberResult;
    }
}

  題目2:一只青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。

  先考慮簡單情況,如果只有一級臺階,那麽結果很顯然是1.如果有兩級臺階,那麽我們就有兩個選擇了,一種是一次跳一級,跳兩次,另外一種是一次跳兩級。

  接著考慮一般情況,把n級臺階時的調發看做n的函數f(n),當n>2時,如果第一次跳一級那麽我們可以表示成1+f(n-1),若第二次跳兩級我們可以表示成2+f(n-2),第一種情況有f(n-1)種方案,第二種方案有f(n-2)種方案,這樣,總體我們就有f(n)=f(n-1)+f(n-2)種方案,不難發現這實際上就是斐波那契數列。

public class Solution {
    public int JumpFloor(int target) {
        int[] a ={0,1,2};
        
        if(target<=2){
            return a[target];
        }
        
        int numberOne = 1;
        int numberTwo = 2;
        int numberResult = 0;
        
        for(int i=3; i<=target; i++){
            numberResult = numberOne + numberTwo;
            numberOne = numberTwo;
            numberTwo = numberResult;
        }
        
        return numberResult;
    }
}

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

  這道題目可以沿用上一題的思路,如果只有一級臺階,那麽只有一種法案,如果有兩級臺階我們就回到了上一題f(2)=f(2-1)+f(2-2),如果有三級臺階那麽我們可以第一次跳一級1+f(3-1),第一次跳兩級2+f(3-2),或者第一次跳三級3+f(3-3),可得出f(3)=f(3-1)+f(3-2)+f(3-3)。

  當有n級臺階時,f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)+f(n-1)

  當有n-1級臺階時,f(n-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

  不難發現f(n)=2*f(n-1),一個等比數列,易得f(n)=2^(n-1)

public class Solution {
    public int JumpFloorII(int target) {
        int jumpNumber = 1;
        while((--target)!=0){
            jumpNumber*=2;
        }
        return jumpNumber;
    }
}

  題目4:

  我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?

  這題依舊是上面的思想,只是理解上有點小坑。

public class Solution {
    public int RectCover(int target) {
        int a[] = {0,1,2};
        
        if(target<=2){
            return a[target];
        }
        
        int numberOne = 1;
        int numberTwo = 2;
        int numberResult = 0;
        
        for(int i=3;i<=target;i++){
            numberResult = numberOne + numberTwo;
            numberOne = numberTwo;
            numberTwo = numberResult;
        }
        
        return numberResult;
    }
}

  

劍指offer(7)