一、简单介绍
1、递归的本质
递归的本质:将原来的问题,转换成更小的同一个问题。
2、递归的实现条件
一个问题的解可以分解成几个子问题的解。
这个问题与与分解的子问题,除了数据规模不同,求解完全一样。
存在递归终止条件。
3、递归的两个重要属性
终止条件和递推公式。
二、代码案例
1、利用递归实现数组元素的相加。
public static int getSum(int[] arr) {
int sum = getSum(arr, 0);
return sum;
}
//计算 arr[l,length) 的值
private static int getSum(int[] arr, int l) {
if (l == arr.length - 1) { //递归的结束条件
return arr[l];
}
return arr[l] + getSum(arr, l + 1); //把原问题,转化成更小的问题
}
2、利用递归实现链表中的元素。
//1、递归实现删除掉链表中的重复元素
public static ListNode removeElements(ListNode head, int val) {
if(head==null) return null; //如果链表为 null 我们就不需要任何操作
if(head.val==val){ //如果头节点的val 则是要删除的元素。
return removeElements(head.next,val) ;
}else{ //如果头节点不为val 则删除头节点
head.next= removeElements(head.next,val);
}
return head;
}
3、利用递归来实现避免重复元素的递归。
//走的台阶个数
public int fn(int i){
if(i==1) return 1;
if(i==2) return 2;
return fn(i-1)+fn(i-2); //f(n-1) 表示的是第一步走一步台阶的情况。 f(n-2) 表示的是第一次走二步,后的走法。
}
public Map< Integer, Integer> map=new HashMap<>();
//走的台阶个数
public int fn2(int i){
if(i==1) return 1;
if(i==2) return 2;
if(map.containsKey(i)) return map.get(i);
int ret =fn(i-1)+fn(i-2); //f(n-1) 表示的是第一步走一步台阶的情况。 f(n-2) 表示的是第一次走二步,后的走法。
map.put(i,ret);
return ret;
}
三、总结
总结:写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递
推公式,然后再推敲终止条件,最后将递推公式和终止条件翻译成代码。
编写递归代码的关键是,只要遇到递归,我们就把它抽象成一个递推公式,不用想一层层
的调用关系,不要试图用人脑去分解递归的每个步骤。