斐波那契數列的相關問題
第0項為0,第1項為1,第2項為1,第3項為2…後面的項是之前兩項的和。 這種後面的內容恰好需要前面的值得讓人一下就想到了遞迴。
public static int fibonacci(int n) {
if(n == 0){
return 0;
}else if(n == 1||n==2){
return 1;
}else return (fibonacci(n-1)+fibonacci(n-2));
}
再暴力一點!
public static int fibonacci(int n) { (n<2)? return n : return (fibonacci(n-1)+fibonacci(n-2)); }
看似簡便但是對於fibonacci(n-1)和fibonacci(n-2)來說每個都要單獨遞迴一遍實在很麻煩。而且數字一大還會產生棧溢位的現象。解決的辦法就是用空間換時間改成用陣列去記憶之前所運算的值:
public static int fibonacci1(int n){ int[] arr = new int[n+1]; arr[0] = 0;arr[1]=1; for(int i = 2;i<=n+1;i++){ arr[i]=arr[i-1]+arr[i-2]; } return arr[n+1]; }
其實用迭代的思路也能實現記憶功能(動態規劃)//其實只需要兩個變數我這裡寫麻煩了
public static int fibonacci2(int n){ if(n<=1){return n;} int fibonacci1 = 0,feibonacci2=1,feibonacci3 =0; for(int i = 2;i<=n;i++){ feibonacci3 = fibonacci1 + feibonacci2; fibonacci1 = feibonacci2; feibonacci2 = feibonacci3; } return feibonacci3; }
但是資料一大這就出現了毛病,我無法求第50項的值。換成long?可是再超過範圍了又該怎麼辦?? 這裡就需要用到大數計算
public static BigInteger fibonacci3(int n) {
if(n == 0){
return BigInteger.valueOf(0);
}else if(n==1 ){
return BigInteger.valueOf(1);
}else return fibonacci3(n-1).add(fibonacci3(n-2));
}
BigInteger a = new BigInteger(“1”);//構造a.add(b)//相加subtract();// 相減multiply(); //相乘divide(); //相除取整remainder();// 取餘
這是斐波那契第50項的值,下面一行是所用時間,10分多鐘吧。不得不說是真的卡。。。但是總算是算出來了。 好吧50項都十分鐘了那51項還不得20多分鐘???所以就需要用到矩陣的思想去解決。 奈何我數學不好,以後有機會再填這個坑。
斐波那契的思想還可以解決變態上樓梯的問題。一隻青蛙每次可以上一階或者兩階臺階。有n階臺階請問有多少種方法? 不用遞迴的思想解決如下所示
public static int jump(int n) {
//首先求出最多有多少次跳偶數階臺階
int evenMix = n / 2;
//下來思考在一堆1裡面插入0個2乃至n/2個分別有多少種辦法最後求和
int sum = 0;
for (int i = 0; i <= evenMix; i++) {//i 本次2階的個數,
int count = n - i;//跳本次總jump數
sum = sum + factorial(count)/factorial(count-i)/factorial(i);
}return sum;
}
public static int factorial(int n) {
int sum = 1;
while (n > 0) {
sum = sum * n--;
}
return sum;
}
運用遞迴 求n階有多少種可能,最後一步無非就只可能跳1階或者2階,最後跳1階的可能即n-1階臺階的所有可能,最後跳2階的可能即跳n-2階臺階的所有可能。故n階即為兩者之和。恰好滿足斐波那契數列。
現在青蛙升級了每次可以跳1~n個臺階,請問n個臺階共有多少種方法。 還是通過最後一步分析,最後一步可以1~n階 最後1階時 方法等於n-1階 最後2階時 方法等於n-2階 … 最後n階時 方法等於n-n階//跳0階時次數為1 程式碼如下:
public static int jumpplus(int n){
int sum = 0;
if(n<2){return 1;}
else {
for(int i=1;i<=n;i++)
sum+=jumpplus(n-1);
}
return sum;
}