递归的真正解题步骤

递归的解题步骤

  1. 题目要求的返回值是什么?

  1. 我们要用递归函数来求什么(也就是我们通过调用递归函数要得到什么)?

  1. 递归的出口是什么?

  1. 在某一层我们要做些什么?

只要对每一道题按步骤做好以上分析,不但做得快,而且可以真正理解递归的过程.

活不多说,我们用例子来说明:

递归解题例子一

下面我们按照以上步骤来分析解题

  1. 题目要求的返回值是什么?

显然题目让我们返回让我们返回合并完成后链表的头结点;所以我们要return l1;或者return l2;

  1. 我们要用递归函数来求什么(也就是我们通过调用递归函数要得到什么)?

首先题目要我们合并两个有序链表,所以我们是调用递归函数来合并链表

又因为我们要返回的是合并后链表的头结点

所以我们通过调用递归函数来得到两个链表中下一个较小的值,

即 l1.next=merge(l1.next,l2)或者 l2.next=merge(l2.next,l1)

  1. 递归的出口是什么?

因为两个链表是有序的,所以当其中一个链表为空了之后,只要把当前较小值的链表结点返回即可

然后在回溯的后可以得到合并后链表的头结点

  1. 在某一层我们要做些什么?

在某一层,我们要做的是找到下一个较小值,并把当前最小值所在链表的头结点返回返回

在当前层就可以想成这就是第一层,所以只需

1.找到下一个较小值

2.返回当前最小值所在链表的头结点

然后让我们来根据以上分析来写代码

//题目要求我们返回链表头结点所以递归函数的返回值为ListNode
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    //递归的出口是当其中一个链表为空,直接返回另一个链表的头结点,
    //在当前层返回的就是头结点
        if (l1 == null) {
            return l2;
        }
        else if (l2 == null) {
            return l1;
        }
        else if (l1.val < l2.val) {
     //   在当前层就可以想成这就是第一层,所以只需
     //      1.找到下一个较小值
     //      2.返回当前最小值所在链表的头结点
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }
        else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }

    }

递归的解题步骤进化版

  1. 递归的出口是什么?

  1. 在某一层我们要做些什么?

其实在理解了之后我们只用考虑着两步,因为递归的返回值和递归函数要干些什么事是变化的

也可以说是为了实现功能而不同设计的

下面我们来看第二个例子

递归解题例子二

解题思路:显然用递归来设计程序的话,我们需要得到头结点head和尾结点tail但是这是一个链表我们需要通过遍历才能获取tail,所以我们想能不能直接把递归函数的作用就是获取当前层的tail

然后当传入的链表只要一个或者两个元素的时候,就可以直接返回head.next或者head.next.next

所以我们就得到了:

1.递归出口是: 当链表长度为1或者2时直接返回head.next或者head.next.next

if (len == 1) {

ListNode outTail = head.next;

head.next = null;//要置为空因为它原本是指向上一层的下一个结点

return outTail;

}

if (len == 2) {

ListNode outTail = head.next.next;

head.next.next = null;

return outTail;

}

2.在某一层我们要做些什么: 调用递归函数reorderListHelper(head.next,len-2)获取tail后

让head指向tali,让tail指向下一次要递归的子链表的头结点,返回上一层的尾结点outTail=tail.next;

  public void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) return;
        int len = 0;
        ListNode h = head;
        while (h != null) {
            len++;
            h = h.next;
        }
         reorderListHelper(head, len);
    }

    private ListNode reorderListHelper(ListNode head, int len) {
        if(len==1){
            ListNode outTail=head.next;
            head.next=null;
            return outTail;
        }
        if(len==2){
            ListNode outTail=head.next.next;
            head.next.next=null;
            return outTail;
        }

        ListNode tail=reorderListHelper(head.next,len-2);
        ListNode outTail=tail.next;
        tail.next=head.next;
        head.next=tail;
        return outTail;

    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值