五個遞歸題總結


遞歸

  • 電影院
  • 求階乘
  • 斐波那契數
  • 數字反轉
  • 求台階走法數

當然,很多遞歸都是可以優化的,比如f(n)=f(n-1)+f(n-2),這里f(n-2)就會計算兩次,可以用散列表存儲已經計算的數據,但是這里主要演示遞歸思想,不再進行優化。

電影院

周末你帶着女朋友去電影院,女朋友問你,咱們現在坐在第幾排啊,電影院太黑沒法數怎么辦,於是你問前一排的人他是第幾排,你只需要在他的數字上加一就知道自己是第幾排,但是前面的人也看不清啊。所以他也問前面的人,就這樣一排一排的問直到問到第一排的人

  • 這是一個非常標准的遞歸求解問題的分解過程,去的過程叫遞,回來的過程叫歸。基本上,所有的遞歸問題都可以用遞推公式來表示。剛剛這個生活中的例子,我們用遞推公式將它表示出來是這樣的:

f(n) = f(n-1) +1 其中,f(1) = 1

  • f(n)代表你想知道自己在哪一排,f(n-1)表示前面一排所在的排樹。核心代碼如下:
public static int cinemas(int n){
        if (n == 1)
            return 1;
        return cinemas(n-1)+1;
    }

求階乘

求階乘思路跟上面差不多,其遞推式為:

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

  • 核心代碼如下:
    public static  int recursion(int n){
        if (n == 1) return 1;
        return recursion(n-1)*n;
    }

斐波那契數

斐波那契數的排列是:0,1,1,2,3,5,8,13,21,34,55,89,144……。依次類推下去,你會發現,它后一個數等於前面兩個數之和,在這個數列中的數字,就被稱為斐波那契數

  • 很容易得到斐波那契數的遞推式為:

    f(n) = f(n-1) + f(n-2),其中f(0) = 0,f(1) = 1

  • 核心代碼如下:

public static int recursion(int n){
        if (n <= 1) return n;
        return recursion(n-1) +recursion(n-2);
    }

數字反轉

反轉數字

  • 反轉一個數字,可以用遞歸方法,直接上代碼
public static void recursion(int n){
        System.out.println(n % 10);

        if (n >= 10){
            recursion(n / 10);
        }
    }

求台階數

假設這里有n個台階,每次你可以跨1個台階或者兩個台階,請問走這n個台階有多少種走法。

  • 每一次有兩種走法,結束的條件是n = 1的時候只有一種走法,n = 2的時候有兩種走法
    ,遞歸式如下:

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

  • 核心代碼如下:

public static int recursion(int n){

        if (n == 1) return 1;
        if (n == 2) return 2;
        return recursion(n-1)+recursion(n-2);

    }

總結:

遞歸需要滿足三個條件

  • 一個問題的解可以分為幾個子問題的解
  • 這個問題與分解后的子問題,除了數據規模不同,求解方式相同
  • 存在遞歸終止條件

遞歸代碼要警惕堆棧溢出

函數調用會使用棧來保存臨時變量。每調用一個函數,都會將臨時變量封裝為棧幀壓入內存棧,等函數執行完成返回時,才出棧。系統棧或者虛擬機棧空間一般都不大。如果遞歸求解的數據規模很大,調用層次很深,一直壓入棧,就會有堆棧溢出的風險。可以用一個變量設置做多遞歸多少次,超過一定次數自己拋出異常

遞歸代碼要警惕重復計算


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM