Java版牛客網劍指offer編程題第7題--斐波拉契數列

        跟learnjiawa一起每天一道算法編程題,既可以增強對常用API的熟悉能力,也能增強自己的編程能力和解決問題的能力。算法和數據結構,是基礎中的基礎,更是筆試的重中之重。

  • 不積硅步,無以至千里;
  • 不積小流,無以成江海。

題目描述

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

我的想法

  • 斐波拉契數列,第n(n>=2)項等於前兩項的和,即F(n)=F(n-1)+F(n-2),n>=2且爲正整數。
  • 斐波拉契數列很明顯體現的是一個遞歸思想。
  • 遞歸求解很簡單,但是重複計算了很多次已知值,怎麼優化?

解題方法1

    /**
     * 遞歸求解
     * */
    public static int Fibonacci(int n) {
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        /**
         * 重複計算次數太多,比如n=8,程序會去計算F(7)和F(6)
         * 爲了計算F(7),程序又會再去計算F(6)和F(5),這樣就重複計算了已知值
         * 時間開銷大,並且容易棧溢出。
         * */
        int result = Fibonacci(n-1) + Fibonacci(n-2);
        return result;
    }

解題方法2

    /**
     * 優化:用一個數組將每個值存起來,需要的時候直接取,不用重複計算
     * */
    public static int Fibonacci2(int n) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(0);
        list.add(1);
        if(n <= 1){
            return list.get(n);
        }else{
            for(int i = 2; i <= n; i++){
                list.add(list.get(i-1)+list.get(i-2));
            }
            return list.get(n);
        }

    }

代碼測試

package com.learnjiawa.jzoffer;

import java.util.ArrayList;

/**
 * @author zouhuayu
 * 2019-12-06-9:38
 */
public class Solution7 {
    public static void main(String[] args) {
        int n = 23;
        System.out.println("斐波拉契數列第"+n+"項是"+Fibonacci2(n));
    }

    public static int Fibonacci(int n) {
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        /**
         * 重複計算次數太多,比如n=8,程序會去計算F(7)和F(6)
         * 爲了計算F(7),程序又會再去計算F(6)和F(5),這樣就重複計算了已知值
         * 時間開銷大,並且容易棧溢出。
         * */
        int result = Fibonacci(n-1) + Fibonacci(n-2);
        return result;
    }

    /**
     * 優化:用一個數組將每個值存起來,需要的時候直接取,不用重複計算
     * */
    public static int Fibonacci2(int n) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(0);
        list.add(1);
        if(n <= 1){
            return list.get(n);
        }else{
            for(int i = 2; i <= n; i++){
                list.add(list.get(i-1)+list.get(i-2));
            }
            return list.get(n);
        }

    }
}

總結

題目主要考察遞歸和循環的相關知識點,先實現,再優化,迅速解題。

參考文獻

[1]程傑. 大話數據結構. 北京:清華大學出版社, 2011.

更多

對我的文章感興趣,持續更新中…
關注微信公衆號:
LearnJava

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章