a.宏观描述:本质上说,递归将原问题转化为更小的同一问题。
b.递归本身也是一个函数,来完成某一功能。
1.递归终止的条件
2.递归操作
1.猴子吃桃问题
猴子第一天偷吃了该堆桃子的一半,觉得好吃多吃了一个;第二天吃了该堆桃子的一半,觉得好吃多吃了又一个,... ,到了第四天,只剩下了一个桃子,问猴子一个偷吃了多少桃子?
一般做法:
package com.ffyc.lesson.deliver;
//猴子吃桃问题
public class MonkeyEatPeach {
public int eatPeach1(){
return (eatPeach2()+1)*2;
}
public int eatPeach2(){
return (eatPeach3()+1)*2;
}
public int eatPeach3(){
return (eatPeach4()+1)*2;
}
public int eatPeach4(){
return 1;
}
public static void main(String[] args) {
MonkeyEatPeach monkeyEatPeach=new MonkeyEatPeach();
//int result =monkeyEatPeach.eatPeach1();
int result =monkeyEatPeach.eatPeach();
System.out.println(result);
}
}
递归做法:
package com.ffyc.lesson.deliver;
//猴子吃桃问题
public class MonkeyEatPeach {
//递归方法
public int eatPeach(int days){
//递归终止条件
if(days==1){
return 1;
}
//递归操作
return (eatPeach(days-1)+1)*2;
}
public static void main(String[] args) {
MonkeyEatPeach monkeyEatPeach=new MonkeyEatPeach();
//int result =monkeyEatPeach.eatPeach1();
int result =monkeyEatPeach.eatPeach(4);
System.out.println(result);
}
}
2.数组求和问题
一般做法:
public class SumArr {
public int sum(int[] arr){
int sum=0;
//对入参进行判断
if(arr==null){
return sum;
}
int length=arr.length;
for(int i=0;i<length;i++){
sum+=arr[i];
}
return sum;
}
public static void main(String[] args) {
int[] arr={1,3,5,7,9};
SumArr sumArr=new SumArr();
System.out.println(sumArr.sum(arr));
}
}
递归做法:
public class SumArr {
public int sum(int[] arr){
//对入参进行判断
if(arr==null){
return 0;
}
return sumDG(arr,0);//求整个数组的和,其左边界是0
}
/**
*
* @param arr
* @param l 表示所求数组的左边界
* @return
*/
public int sumDG(int[] arr,int l){
//1.递归中终止条件
if(l==arr.length){
return 0;
}
//2.递归操作
return arr[l]+sumDG(arr,l+1);
}
public static void main(String[] args) {
int[] arr={1,3,5,7,9};
SumArr sumArr=new SumArr();
System.out.println(sumArr.sum(arr));
}
}
3.链表实现递归
链表具有天然的递归结构。
将下面列表从0之后断开,则:
链表中删除元素问题
public void deleteNode(T val){
/*
此处代码在递归方法中可实现
//入参判断
if(this.header==null){
return;
}
*/
//递归操作
this.header=deleteNode(this.header,val);
}
//递归方法(从以node为头结点的链表中删除元素val)
public Node deleteNode(Node node ,T val){
//递归终止的条件
if(node==null){
return null;
}
//递归操作
Node e=node;
Node nextHeader=node.next;
if(e.val==val){
return nextHeader;
}else{
e.next=deleteNode(nextHeader,val);
return e;
}
}
4.链表的旋转
一般做法:
public class Solution206 {
public class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val,ListNode next) {
this.val = val;
this.next = next;
}
}
public ListNode reverseList(ListNode head){
//一般做法:
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
//先保存cur的下一个结点
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
//此时pre指向的是新链表的头结点
return pre;
}
}