宏观视角看递归
通过数组求和看递归的基本性质
链表的天然递归性
01
通过数组求和看递归的基本性质
// begin 表示从数组中哪个索引位置开始
// 当begin == arr.length表示数组中没有剩余元素
if (begin == arr.length) {
return 0;
}
二是要知道递归递推公式,就数组求和这个问题来说,递推公式是:
arr[begin] + sum(begin + 1, arr);
有了终止条件和递推公式,就可以写出递归求解数组中所有元素和的代码了,实现如下:
public int sum (int[] arr) {
// 调用递归函数,初始从0开始
return sum(0, arr);
}
// 递归函数
private int sum(int begin, int[] arr) {
// begin 表示从数组中哪个索引位置开始
// 当begin == arr.length表示数组中没有剩余元素
if (begin == arr.length) {
return 0;
}
// 我只计算我拿到的数组中第一个元素的值
// 和数组中剩余元素总和的和
return arr[begin] + sum(begin + 1, arr); // 递归调用
}
这里我们在第7行sum(int begin, int[] arr)这个方法中调用了sum(int begin, int[] arr)方法它自己,即16行的sum(begin + 1, arr),这一点可能会让你觉得困惑。
我们可以这样理解,方法sum(int begin, int[] arr)是计算数组中从索引begin开始所有元素的总和,而该方法的计算规则是我计算的是当前数组起始位置begin所对应的元素值和数组中剩余元素的总和的和。那么,我就需要有个方法可以告诉我数组中剩余元素的总和是多少。
这时,刚好有个方法fun(int begin, int[] arr),只要我告诉它数组是什么样的,以及从哪个索引位置开始计算,它就会告诉我数组中剩余元素的总和。只不过这个方法fun(int begin, int[] arr)所需的参数和我自己一样而已。于是,在代码中看起来就是方法sum(int begin, int[] arr)调用了它自己。
02
链表的天然递归性
接着我们看下如何用递归思想解答LeetCode中#203.移除链表元素这个问题。
题目描述:
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
LeetCode
public ListNode removeElements(ListNode head, int val) {
// 递归终止条件
if (head == null) {
return null;
}
// 调用方法removeElements将当前结点之后的链表部分中的
// 和val值相等的结点删除
ListNode result = removeElements(head.next, val);
// 如果当前结点head的值等于val则返回result
if (head.val == val) {
return result;
} else {
// 如果当前结点head的值不等于val则
// 将result挂在当前结点head之后返回
head.next = result;
return head;
}
}
题图:stux / Pixabay
评论