递归 算法专题

递归题目技巧

  1. 什么是递归
    函数自己调用自己的情况
  2. 为什么会用到递归
    本质: 主问题, 可以拆分成相同的子问题
    子问题, 又可以拆分出相同的子问题
  3. 如何理解递归?
    宏观的看待递归的过程
    1)不要在意递归的细节展开图
    2)把递归的函数当成一个黑盒
    3)相信这个黑盒一定能够完成这个任务
  4. 如果写好一个递归?
    1)先找到相同的子问题(变得值)-----函数头的设计
    2)只关心某个子问题是如何解决的-----函数体的书写
    3)注意一下函数递归的出口
  5. 循环(迭代)和递归本质是可以相互转化的
    循环, 适用于只有一层递归的情况, 例如链表
    递归, 适合多层, 例如二叉树, 多叉树...

一. 汉诺塔问题

汉诺塔问题

java 复制代码
class Solution {
    public void hanota(List<Integer> a, List<Integer> b, List<Integer> c) {
        dfs(a, b, c, a.size());// 从a借助b移动到c, 移动n个盘子
    }

    public void dfs(List<Integer> a, List<Integer> b, List<Integer> c, int n) {
        if (n == 1) {
            c.add(a.remove(a.size() - 1));
            return;
        }
        dfs(a, c, b, n - 1);
        c.add(a.remove(a.size() - 1));
        dfs(b, a, c, n - 1);

    }
}

二. 合并两个有序链表

合并两个有序链表

java 复制代码
/**
 * Definition for singly-linked list.
 * 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; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//合并两个有序链表
        if(l1 == null) return l2;
        if(l2 == null) return l1;

        if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next, l2);//l1小, 合并l1.next 和 l2两个有序链表
            return l1;
        }else{
            l2.next = mergeTwoLists(l1, l2.next);//l2小, 合并l2.next 和 l1两个有序链表
            return l2;
        }
        
    }
}

三. 反转链表

反转链表

java 复制代码
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode newHead = reverseList(head.next);//将head结点后面的逆序, 返回逆序后的头结点
        head.next.next = head;//将head结点插在逆序链表最后
        head.next = null;//将head.next置为空
        return newHead;
    }
}

四. 两两交换链表中的结点

两两交换链表中的结点

java 复制代码
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode newHead = swapPairs(head.next.next);//将head.next.next 后面的链表两两交换, 返回头结点
        ListNode ret = head.next;
        head.next.next = head;//将前两个链表交换
        head.next = newHead;

        return ret;

    }
}

五. pow(x, n)

算法: 快速幂

实现快速幂: 1. 递归 2. 循环

java 复制代码
class Solution {
    public double myPow(double x, int n) {
        return n < 0 ? 1.0 / pow(x, -n): pow(x, n);
    }
    public double pow(double x, int n){
         if(n == 0) return 1.0;
        double tmp = pow(x, n / 2);//先算一半
        return n % 2 == 0? tmp * tmp : tmp * tmp * x;//结果乘在一起
    }
}
相关推荐
tangguofeng10 分钟前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆1 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的2 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
老歌老听老掉牙2 小时前
麻花钻切屑形态演变的力学机制与临界条件分析
python·算法·钻头
zhangfeng11333 小时前
国产GPU/AI算力芯片现状(修订完整版 · 截至2026年9月
人工智能·算法·ai编程·npu
学代码的CJY3 小时前
从代码出发理解时间复杂度与空间复杂度
数据结构·算法
白帽攻防录3 小时前
SRC 挖洞:WSO2 JWT 算法混淆绕过深度复盘,CVE-2026-5430 不支持的算法怎么变成管理员
网络·算法·安全·网络安全·jwt
小O的算法实验室4 小时前
IEEE TEVC,基于精确与DQN群智能调度方法用于多目标异构USV
算法
可乐ea5 小时前
AI Agent 工具调用准确性评测:选择错误与参数错误分开测
大数据·人工智能·算法·大模型·工具调用·ai智能体·agent评测
上位机妹子5 小时前
C 语言 数组删除指定元素(快慢指针法)
c语言·数据结构·算法