通过解决数组求和理解递归

如何理解递归

本质上是将原来的问题转化为更小的同样的问题,问题的规模可以逐渐缩小,通常小到不能再小的时候,会更加容易的解决。

举一个简单的例子:数组求和

  • 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之间所有数字的和。(递归函数的宏观语意)递归函数本身也是一个函数,完成一个功能。把需要调用的递归函数想像成一个子过程,思考子过程如何帮助自己解决问题。

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