通過解決數組求和理解遞歸

如何理解遞歸

本質上是將原來的問題轉化爲更小的同樣的問題,問題的規模可以逐漸縮小,通常小到不能再小的時候,會更加容易的解決。

舉一個簡單的例子:數組求和

  • Sum(arr[0...n-1]) = arr[0]+Sum(arr[1...n-1]) 得到一個更小同一問題
    求數組中n個數的和,其實等於把索引爲0的數拿出來加上第1到n-1所有元素的和。在這兩個Sum函數中,第二個sum要比第一個更小,因爲第一個sum需要求n個數的和,而第二個只需要對n-1個數求和。
    上述過程依次類推
  • Sum(arr[1...n-1]) = arr[1]+Sum(arr[2...n-1]) 得到更小統一問題
  • ······
  • Sum(arr[n-1...n-1]) = arr[n-1]+Sum(arr[]) 最基本的問題
    對一個數字求和就等於這個數組加上對空數組求和,空數組的和爲0。

將最基本的問題解決了之後,根據上面所述的一系列邏輯就可以將原問題解決。

使用遞歸解決數組求和

Sum.java

public class Sum {

    // 用戶操作的函數
    public static int sum(int[] arr) {
        // 遞歸的初始調用是從0開始到n-1
        return sum(arr, 0);
    }


    // 計算arr【l...n)這個區間所有數字的和 l-(n-1)的和
    // 真正的遞歸的函數
    private static int sum(int[] arr, int l) {
        // 當左邊界l等於數組長度的時候 即整個數組爲空的時候
        if (l == arr.length)
            return 0;
        return arr[l] + sum(arr, l + 1);
    }
    
	// 聲明一個數組進行main函數測試
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println(sum(nums));
    }

}

測試結果:

55

遞歸算法的基本原則

通過數組求和完成了一個遞歸函數sum()

 private static int sum(int[] arr, int l) {
        if (l == arr.length)
            return 0;
        return arr[l] + sum(arr, l + 1);  // 讓arr[l] 加更小的一段數組中所有元素的和
}

所有的遞歸算法都是可以分成兩部分:

  1. 求解最基本的問題,這個問題是需要編寫邏輯求解的。通常最基本問題都是非常簡單的。
  2. 把原問題轉化成更小的問題,也是遞歸算法最核心的部分。不是簡單的求一個更小的問題的答案,而是根據更小問題的答案構建出原問題的答案。

在寫遞歸函數時一定要注重遞歸函數本身的語意。
對於求和sum來說,它本身就是計算l…n-1之間所有數字的和。(遞歸函數的宏觀語意)遞歸函數本身也是一個函數,完成一個功能。把需要調用的遞歸函數想像成一個子過程,思考子過程如何幫助自己解決問題。

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