算法刷题笔记-递归解题方法总结

一、四条基本法则

  1. 基准情形:基准情形下,无需递归就可以解出;
  2. 不断推进:每一次递归调用都必须要使状况朝向一种基准情形推进;
  3. 设计法则:假设所有的递归调用都能运行;
  4. 合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。
// LeetCode 206. 反转链表
ListNode reverse(ListNode head) {
    if (head.next == null) return head; //基准情形
    ListNode last = reverse(head.next); //不断推进;设计法则:调用递归时,不要再次跳进递归,直接用就好。
    head.next.next = head;	
    head.next = null;
    return last;

二、构造递归思路

  1. 明确递归函数定义:后面调用时直接使用,不要再次跳进递归;
  2. 调用已定义的递归函数:找到初始逻辑,对剩余部分调用递归函数,以满足“不断推进”
  3. 补全递归函数逻辑;
  4. 补全基准情形:跳入递归,找到终止逻辑,便是基准情形;
// LeetCode 206. 反转链表
// 1.明确递归函数定义:输入一个节点 head,将「以 head 为起点」的链表反转,并返回反转之后的头结点。
ListNode reverse(ListNode head) {
    if (head.next == null) return head;	// 4.补全基准情形:跳入递归,找到基准情形。
    ListNode last = reverse(head.next);	// 2.调用已定义的递归函数:满足“不断推进”,链表的头节点head每次前进一个节点。
    // 3.补全递归函数逻辑
    head.next.next = head; 
    head.next = null;
    return last;

三、经典题型解析

 这类经典题型,可以直接套用对应的解题方法,不用再代入上面的通用方法。

3.1 遍历链表

  1. LeetCode 25. K 个一组翻转链表:这道题有助于理解初始逻辑和终止逻辑,好好品一下。
// 25. K 个一组翻转链表
ListNode reverseKGroup(ListNode head, int k) {
    if (head == null) return null;
    ListNode a, b;
    a = b = head;
    for (int i = 0; i < k; i++) {
        if (b == null) return head; // 终止逻辑:不足 k 个,不需要反转,base case。
        b = b.next;
    }
    ListNode newHead = reverse(a, b); // 初始逻辑:反转前 k 个元素。
    a.next = reverseKGroup(b, k);
    return newHead;
}

3.2 遍历二叉树

参考

labuladong的算法小抄
LeetCode 206. 反转链表
LeetCode 92. 反转链表 II
LeetCode 25. K 个一组翻转链表

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值