1. 程式人生 > >劍指offer——(3)斐波那契數列&&跳臺階&&瘋狂跳臺階進階版&&矩形覆蓋

劍指offer——(3)斐波那契數列&&跳臺階&&瘋狂跳臺階進階版&&矩形覆蓋

 這兩道題 其實相同。

public class Solution {
/*
    一看到題目就想到用遞迴,結果雖然能通過,但時間還是太長
*/
    public int Fibonacci(int target) {
	        return hhh(target);
	    }
	    
	    int hhh(int n){
	        if(n==1||n==2) return 1;
	        if(n==0) return 0; //牛客網提交沒有這一句提示stackoverflow
	        return hhh(n-2)+hhh(n-1);
	    } 
	
}

public class Solution {
/*
    仔細看題目,已經給出了n的極限是39,可以直接定義一個數組儲存0-39的所有斐波那契數
*/
    public int Fibonacci(int target) {
	    int arr[] = new int[40];
        arr[0] = 0;
        arr[1] = 1;
        //習慣從兩個1開始的斐波那契數,在這裡直接賦值也減少了下面的一次迴圈,for的i從3開始
        arr[2] = 1; 
        for(int i=3;i<=39;i++){
            arr[i] = arr[i-1] + arr[i-2];
        }    
        return arr[target];
	 }	
}

public class Solution {
    public int Fibonacci(int target) {
	    int arr[] = new int[40];
        arr[0] = 0;
        arr[1] = 1;
        //同上 多一次迴圈時間就長一些
        for(int i=2;i<=39;i++){
            arr[i] = arr[i-1] + arr[i-2];
        }    
        return arr[target];
	    }	
}

public class Solution {
/*
    尾遞迴 時空間最優!
*/
    public int Fibonacci(int target) {
	    return hhh(0,1,target);   
	}	
    int hhh(int x,int y,int z){
        if(z==0) return 0;
        if(z==1) return y;
        // 斐波那契數只需要知道當前位置前面的兩個數即可相加得出當前的數值
        // 所以我們把前兩個數值加入遞迴條件 避免了n!的複雜度
        return hhh(y ,x+y ,z-1);
    }
}

這道題說來慚愧,本人沒有做出來。。不過一旦知道了解題思路一輩子都不會忘,方法也很簡單。

簡單地說 這就是一道數學題 

青蛙在n-1級臺階上 都可以選擇跳與不跳 最後一級n階一定要跳 運用排列組合的知識 我們可以得到這麼一條公式:

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

是不是完美?!有了這麼一條公式之後程式碼就完全呼之欲出了。。

在這裡介紹一下效率高的位移(這裡是左移)運算子來計算2的次方:<<  ,拾人牙慧的程式碼如下:

public class Solution {
    public int JumpFloorII(int target) {
        return 1<<(target-1); //1*(2^(target-1))
    }
}

2*1的小矩形可以橫著或者豎著鋪:

n=0或1:1種鋪法;

n=2:2種鋪法,兩塊橫著或者兩塊豎著鋪;

n=3:3種鋪法;1+2

n=4:5種鋪法;2+3

......

n=n:f(n)= f(n-1)+ f(n-2)

public class Solution {
    public int RectCover(int target) {
         return hhh(1,2,target);   
	}	
    int hhh(int x,int y,int z){
        if(z==0) return 0;
        if(z==1) return 1; 
        if(z==2) return y; 
        return hhh(y ,x+y ,z-1);
    }
}