算法系列--递归
一.如何理解递归
递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的
笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来说就是要胆大心细,宏观看待问题
其实很多递归的问题如果从宏观的角度去看,其实特别简单,比如二叉树的后序遍历,他无非就是:
- 你先给我一个根节点
- 访问根节点的左子树
- 访问根节点的右子树
- 再打印当前节点的值
对于每一个节点的操作都是相同的,如果从宏观的角度看,我们可以把一个复杂的二叉树想象成一个只有三个节点的二叉树

把二叉树的后序遍历就当做访问这个只有三个节点的二叉树,按照左右根的顺序遍历
dfs(TreeNode root) {if(root == null) return;dfs(root.left);// 访问左节点dfs(root.right);// 访问右结点println(root.val);// 打印当前节点的值
}
大致总结下来递归问题的思路如下:
分析:根据题目分析,判断是否有重复的子问题,如果有,就可以利用递归解决,设计出函数头,从宏观的角度想,要完成这次操作,这个"接口"需要什么参数(二叉树的遍历需要root,快排需要一个数组和开始结束位置)设计函数体:只关注某一个子问题的具体操作,比如二叉树的后序遍历的子问题就完成三步:访问左子树,访问右子树,打印当前节点递归出口:确定好递归出口,将子问题分割到最小单元进行确定,比如二叉树的遍历当节点为空时就不需要再去执行任何操作了,直接返回即可,快排,分割到数组只有一个数字或者为空时(l >= r)就不需要继续分治了
二.例题解析:
1.汉诺塔问题
链接:https://leetcode.cn/problems/hanota-lcci/description/
分析:
函数头:给我三个柱子和盘子数函数体:先借助c将a上的n-1个盘子移动到b,然后将a剩余的最大的盘子移动到c,再借助a,将b上的n-1个盘子移动到c递归出口:当只有一个盘子的时候,直接移动

代码:
class Solution {public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {int n = A.size();dfs(A,B,C,n);}private void dfs(List<Integer> a, List<Integer> b, List<Integer> c,int n) {// 递归结束条件 只有一个盘子的时候直接移动if(n == 1) {c.add(a.remove(a.size() - 1));return;}// 模拟:借助c,将a上的n-1个盘子移动到b上dfs(a,c,b,n-1);// 将最大的盘子移动到c上c.add(a.remove(a.size() - 1));// 模拟:借助a,将b盘上的n-1个盘子移动到c上dfs(b,a,c,n-1);}
}
2.合并两个有序链表
链接: https://leetcode.cn/problems/merge-two-sorted-lists/
分析:
函数头:两个链表的头结点函数体:判断较小值,合并之后的所有节点,并连接返回的节点递归出口:只有一个节点或者为空

代码:
/*** 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 list1, ListNode list2) {// 递归if(list1 == null) return list2;if(list2 == null) return list1;// 将后面的链表给我合并好,并且返回合并好的节点if(list1.val < list2.val) {list1.next = mergeTwoLists(list1.next,list2);return list1;}else {list2.next = mergeTwoLists(list2.next,list1);return list2;}}
}
3.反转链表
链接: https://leetcode.cn/problems/reverse-linked-list/submissions/514361305/
分析:
函数头:给我头结点,逆序整个链表函数体:逆序之后的所有节点,并且返回逆序之后的头结点,然后和当前节点拼接递归出口:只有一个节点或者为空

代码:
/*** 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 reverseList(ListNode head) {// 递归出口if(head == null || head.next == null) return head;// 函数体 你给我逆置后面的所有链表并且返回新的头结点ListNode newhead = reverseList(head.next);// 反转head.next.next = head;head.next = null;return newhead;}
}
4.两两交换链表中的节点
链接: https://leetcode.cn/problems/swap-nodes-in-pairs/
分析:
函数头:重复子问题就是`给我一个节点,两两交换后面的链表的所有节点函数体:关注每一个子问题要干什么,得到交换后的头节点,然后链接这个头结点递归出口:空或者只有一个节点

代码:
/*** 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 swapPairs(ListNode head) {if(head == null || head.next == null) return head;ListNode ret = head.next;// 最终要返回的节点应该是head.next(是头结点的下一个节点)ListNode newHead = swapPairs(head.next.next);head.next.next = head;head.next = newHead;return ret;}
}
5.Pow(x, n)- 快速幂
链接: https://leetcode.cn/problems/powx-n/submissions/514390268/
分析:
函数头:结合快速幂的思想,递归函数就是求x ^ n的值函数体:每一个子问题的操作,得到x ^ n / 2的值,再判断返回的结果的值递归出口:n == 0

代码:
class Solution {public double myPow(double x, int n) {// 注意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;}
}
相关文章:
算法系列--递归
一.如何理解递归 递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的 笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来…...
【JS】替换文本为emjio表情
最终效果展示 T1 T2 T3 T4 需求 把评论你好帅啊啊啊[开心][开心],[开心] 替换为图片 思路 正则match提取[开心]到一个数组数组去重创建img标签img标签转文本. 。例:(el.outerHTML),将el元素转文本字符串replaceAll…...
Solr完结版
Solr是基于Apache Lucene构建的用于搜索和分析的开源解决方案。提供可拓展索引、搜索功能、高亮显示和文字解析功能。本质是一个java web项目,内嵌Jetty服务器,安装方便。 请求Solr中的控制器,处理完数据后把结果相应给客户端 正向索引&#…...
外包干了5天,技术退步明显。。。。
说一下自己的情况,本科生,19年通过校招进入广州某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…...
Cronos zkEVM 基于 Covalent Network(CQT)数据可用性 API,推动其 Layer2 DeFi 生态更好地发展
在一项旨在显著改善 DeFi 生态的战略举措中,Cronos 与 Covalent Network(CQT)携手合作,以期待 Cronos zkEVM 的推出。这一整合,预计将进一步降低以太坊生态系统的交易成本、提升交易速度,并带来更好的交易体…...
基于SpringBoot的高校办公室行政事务管理系统
采用技术 基于SpringBoot的高校办公室行政事务管理系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringBootMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 页面展示效果 功能清单 教师信息管理 办公室管理 办公物资管…...
Linux系统及操作 (04)
Linux系统及操作 (03) RPM 软件包 网络下载对应软件包光盘镜像文件,具备软件包 Windows 系统软件包的管理 可以指定安装位置安装是集中安装到一个目录Linux 系统 与 Windows 系统相反。 常见的软件包(生态)类型 电脑入侵99%都是通过软件…...
粒子群算法 - 目标函数最优解计算
粒子群算法概念 粒子群算法 (particle swarm optimization,PSO) 由 Kennedy 和 Eberhart 在 1995 年提出,该算法模拟鸟群觅食的方法进行寻找最优解。基本思想:人们发现,鸟群觅食的方向由两个因素决定。第一个是自己当初飞过离食物…...
关于MySQL数据库的学习3
目录 前言: 1.DQL(数据查询语言): 1..1基本查询: 1.2条件查询: 1.3排序查询: 1.3.1使用ORDER BY子句对查询结果进行排序。 1.3.2可以按一个或多个列进行排序,并指定排序方向(升序ASC或降序DESC&#…...
笔试题——得物春招实习
开幕式排练 题目描述 导演在组织进行大运会开幕式的排练,其中一个环节是需要参演人员围成一个环形。演出人员站成了一圈,出于美观度的考虑,导演不希望某一个演员身边的其他人比他低太多或者高太多。 现在给出n个参演人员的身高,问…...
动手做简易版俄罗斯方块
导读:让我们了解如何处理形状的旋转、行的消除以及游戏结束条件等控制因素。 目录 准备工作 游戏设计概述 构建游戏窗口 游戏方块设计 游戏板面设计 游戏控制与逻辑 行消除和计分 判断游戏结束 界面美化和增强体验 看看游戏效果 准备工作 在开始编码之前…...
【极简无废话】open3d可视化torch、numpy点云
建议直接看文档,很多都代码老了,注意把代码版本调整到你使用的open3d的版本: https://www.open3d.org/docs/release/tutorial/visualization/visualization.html 请注意open3d应该已经不支持centos了! 从其他格式转换成open3d…...
C语言经典算法-6
文章目录 其他经典例题跳转链接31.数字拆解32.得分排行33.选择、插入、气泡排序34.Shell 排序法 - 改良的插入排序35.Shaker 排序法 - 改良的气泡排序 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官(一&…...
【计算机考研】杭电 vs 浙工大 怎么选?
想求稳上岸的话,其他几所学校也可以考虑,以留在本地工作的角度考虑,这几所学校都能满足你的需求。 如果之后想谋求一份好工作,肯定优先杭电是比较稳的,当然复习的时候也得加把劲。 这个也可以酌情考虑,报…...
激活函数
优秀的激活函数: 非线性:激活函数非线性时,多层神经网络可逼近所有函数 可微性:梯度下降更新参数 单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数 近似恒等性:当参数初始化为…...
使用Jackson进行 JSON 序列化和反序列化
在Spring应用程序中,您可以通过Maven添加Jackson依赖,并创建一个工具类来封装对象的序列化和反序列化方法。以下是详细步骤: 1. 引入 Jackson 依赖 如果使用 Maven,您可以在 pom.xml 文件中添加以下依赖: <depend…...
Linux/Uinx 系统编程:定时器以及时钟同步
本章讨论了定时器和定时器服务;介绍了硬件定时器的原理和基于Intel x86 的PC中的硬件定时器;讲解了CPU操作和中断处理;描述了Linux中与定时器相关的系统调用、库函数和定时器服务命令;探讨了进程间隔定时器、定时器生成的信号,并通过示例演示了进程间隔定时器。编程…...
(Ubuntu中调用相机花屏)Astra plus深度相机--rgb彩色图像花屏解决方法之一
在调试深度相机的过程中只能能调出深度图像和红外图像 在rviz的image的topic中选择彩色图像的话题不显示图像 1、查看相机的usb序列号 lsusb如上图所示,此相机的USB序列号是2bc5:050f,2bc5:060f 其中050f是显示彩色图像的 在这里可通过拔插相机来确定序列号是哪几…...
iPaaS平台能帮助企业解决什么问题?
随着数字化转型的推进,越来越多的企业开始关注如何提高业务效率和灵活性。iPaaS作为一种新型集成平台,它能够帮助企业解决许多与应用程序和数据集成相关的问题。 它能给企业解决什么问题? 以下是 iPaaS 平台通常能够帮助企业解决的一些问题…...
数学建模(灰色关联度 python代码 案例)
目录 介绍: 模板: 案例:哪些原因影响结婚率 数据标准化: 灰色关联度系数: 完整代码: 结果: 介绍: 灰色关联度是一种多指标综合评价方法,用于分析和评价不同指标之…...
除了ulimit -c unlimited:深入理解Linux core dump机制与高级配置指南
深入Linux核心转储:从基础配置到生产环境实战指南当服务器上的关键应用突然崩溃时,系统管理员最需要的就是一份完整的"事故现场记录"。Linux的core dump机制正是为此而生,它能保存程序崩溃时的内存状态、寄存器值和调用堆栈&#x…...
用Python+OpenCV手把手实现Prewitt边缘检测(附完整代码与效果对比图)
用PythonOpenCV手把手实现Prewitt边缘检测(附完整代码与效果对比图) 边缘检测是计算机视觉中最基础也最关键的预处理步骤之一。想象一下,当你需要让计算机"看清"一张照片中的物体轮廓时,边缘检测算法就是它的"视觉…...
Windows文件夹共享
目标:同一局域网实现在一台计算机上共享文件夹,在另一台电脑访问一、电脑A 1.点击要共享的文件夹 -> 属性 -> 共享2.添加Everyone用户组3.控制面板中网络共享关闭密码保存,在访问时不用输入账号密码。二、电脑B 1.在文件资源管理器路径…...
差分隐私GDP机制紧密度量化:从隐私剖面到∆度量的实践指南
1. 差分隐私GDP机制:从理论到实践,如何量化隐私保护紧密度在差分隐私(Differential Privacy, DP)的实际部署中,尤其是在机器学习的隐私保护训练(如DP-SGD)场景里,我们常常面临一个核…...
3分钟掌握JetBrains IDE试用期重置:终极完整指南
3分钟掌握JetBrains IDE试用期重置:终极完整指南 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter JetBrains IDE试用期重置工具(ide-eval-resetter)是一个开源项目,专…...
JWT弱密钥爆破实战:从HS256签名原理到CTF权限提升
1. 这不是密码学考试,而是一场“密钥猜谜”实战JWT(JSON Web Token)在现代Web系统中早已不是可选项,而是默认配置。登录成功后返回一串形如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsIm5hbWUiOiLnlKjliYkiLCJpYX…...
LeagueAkari:英雄联盟终极自动化助手革命性指南
LeagueAkari:英雄联盟终极自动化助手革命性指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否在英雄联盟游戏中反复经历这…...
Godot 4.2 + C# 避坑指南:手把手教你打包发布你的第一个2D游戏到Steam
Godot 4.2 C# 避坑指南:从开发到Steam发布的完整实战手册当你终于完成心爱的2D游戏开发,准备向全世界展示你的作品时,打包发布这个看似简单的环节往往会成为独立开发者最大的噩梦。特别是使用Godot 4.2搭配C#的项目,从导出设置到…...
使用libusb-win32驱动复活老旧USB硬件:以Elektor Magic Eye为例
1. 项目概述:让老硬件在新时代焕发新生手头有一台十多年前的《Elektor》杂志上刊登的“Magic Eye EM84”复古VFD显示屏项目,想把它接到Windows 10电脑上当个酷炫的CPU占用率显示器,却发现官方提供的“AVR309”USB驱动在新系统上彻底罢工了。这…...
PostgreSQL Merge Join 大白话详解
用生活中最直观的例子,彻底搞懂 Merge Join 是什么、为什么快、什么时候用。一、先从生活场景开始 场景一:两摞乱序试卷找同学 期末考试,老师手里有两摞试卷: A 摞:数学试卷,500 份,乱序堆放B 摞…...
