递归算法讲解2
前情提要
上一篇递归算法讲解在这里
递归算法讲解(结合内存图)
没看过的小伙伴可以进去瞅一眼,谢谢!
递归算法的重要性
递归算法是非常重要的,如果想要进大厂,以递归算法为基础的动态规划是必考的,所以我们一定要好好学习递归算法!
本篇博客继续讲解一些递归的经典demo
demo01
递归实现求int类型的数组arr中前n项和,其中arr.length>=n,并且arr当中的元素总和在[-2147483648, 2147483647]之间
还记得递归三步走吗,我们来回顾一下
1. 明确递归的参数和返回值
很显然递归的参数有两个:数组arr + 要求和的序列长度n;
递归的返回值是我们求得的和,不会超过int类型的取值范围,所以数组求和很明显还是int
2. 明确递归的终止条件
我们已知的部分当中,n最小的情况就是递归的终止条件
我们目前已知的,sum(1)肯定是知道的,等于arr[0];sum(2)也是知道的,等于arr[0]+arr[1];
1比较小,所以n==1就是递归的终止条件
递归就是循环,递归的终止条件就是循环的中止条件
还有一些诸如i==j,i>j,都可能称为递归中止条件
3. 明确递归的单层递归逻辑
递归的单层递归逻辑是最难想到的
其实明确单层递归逻辑,很像是中学数学中,让我们求数列的通项公式,我们需要找规律
假设arr = {3,4,7,1,8,12,47……}
sum(1) = 3,sum(2) = 7,sum(3) = 14,sum(4) = 15……
那么sum(n) = ?
差不多是这样的一个过程
当然,本题目是比较简单的,一眼就能看出来,sum(n) = sum(n-1) + arr[n - 1]
递归难就难在,我们很多时候看不出来这个递归逻辑,此时就需要罗列出来找规律
从结束到开始,从部分到整体,从具象到抽象……
代码
public static void main(String[] args) {int[] arr = {3, 4, 7, 1, 8, 12, 47};System.out.println(sum(arr, 5));}// 返回类型是int, 参数类型是arr和npublic static int sum(int[] arr, int n) {// 前0项和显然是0if (n == 0) {return 0;}// 递归终止条件,返回arr[0]if (n == 1) {return arr[0];}// 单层递归逻辑,需要注意要加上arr[n-1]而不是arr[n],因为数组的下标是[0, arr.length - 1]return sum(arr, n - 1) + arr[n - 1];}
输出结果

demo02
递归实现折半查找
1. 明确递归的参数和返回值
递归参数是数组arr和要查找的值val
以及left,mid,right三个arr下标,用于判断后的移动
返回类型,可以返回找到的数值的下标(int),也可以什么都不返回(void)
2. 明确递归的终止条件
很明显是arr[i] = val,但是我们用谁去充当这个i指针呢?
熟悉折半查找的同学都知道,折半查找需要至少3个指针:left,mid,right
每一个指针都有可能在移动过程中直接指向val,我们应该选择谁当指针i呢?
很明显是mid,mid可以代表所有情况,left和right就不一定,而且可能陷入死循环
比如arr[mid]正好指向val,但是arr[left] != val,那么就会出现,arr[mid]既不大于val,也不小于
mid,但是无法跳出while循环的情况,也就是死循环
3. 明确递归的单层递归逻辑
当arr[mid] != val时执行递归
如果arr[mid]>val,说明val在mid左边,递归到左区间寻找;
如果arr[mid]<val,说明val在mid右边,递归到右区间寻找。
代码
public static void main(String[] args) {// 折半查找的前提是数组有序int[] arr = {1, 4, 34, 51, 432, 1111, 2776};halfSearch(arr, 4, 0, 3, arr.length - 1);}public static void halfSearch(int[] arr, int val, int left, int mid, int right) {if (val == arr[mid]) {System.out.println(val + "找到了,下标是:" + mid);return; }if (val > arr[mid]) {halfSearch(arr, val, mid, (right + mid) / 2, right);// mid + 1也行} else if (val < arr[mid]) {// else即可halfSearch(arr, val, left, (mid + left) / 2, mid);// mid - 1也行}}

此时就会有聪明的小伙伴问了,如果没找到呢,你这种写法会栈溢出啊
其实我们只需要给left和right加一个判断就可以了
public static void main(String[] args) {// 折半查找的前提是数组有序int[] arr = {1, 4, 34, 51, 432, 1111, 2776};halfSearch(arr, 432, 0, 3);}public static int halfSearch(int[] arr, int val, int left, int right) {int mid = (left + right) / 2;if (val == arr[mid]) {System.out.println(val + "找到了,下标是:" + mid);return mid;}if (left <= right) {if (val > arr[mid]) {return halfSearch(arr, val, mid + 1, right);// mid + 1也行} else {// else即可return halfSearch(arr, val, left, mid - 1);// mid - 1也行}} else {System.out.println(val + "没找到!");return -1;}}
如果left都大于right了,arr[mid]还是不等于val,那就说明真的没有这个值
demo03
二叉树的中序遍历
左,根,右---------------->中序遍历
如果一个要访问的结点,存在左子树,那么先访问左子树的最左结点
1. 明确递归的参数和返回值
递归参数是二叉树TreeNode,我们叫它root
返回类型,void即可,我们在遍历途中打印每一个结点的val值即可
2. 明确递归的终止条件
root不断遍历,只要不是空,就可以一直遍历
3. 明确递归的单层递归逻辑

上图这棵树,中序遍历的结果是7,37,13,46,3,19,76,48
因为树是链式结构,我们要遍历一棵树,只能先从根节点开始遍历,不能跨越访问,只能root.left.left……这样访问,这样就令很多同学犯难,我要怎么先从7开始访问呢?
这里其实非常简单,不要想的太复杂
我们仍然先从根节点开始访问,然后访问左子树,最后访问右子树
但是我们在访问左子树结束后再打印,我们只需要保证打印顺序是左根右即可
伪代码(不能运行!!!)
public static void middle(TreeNode root) {if (root == null) {return;}// root不是null,先判断左孩子是不是null,再判断右孩子是不是nullmiddle(root.left);System.out.println(left.val);middle(root.right);}
相关文章:
递归算法讲解2
前情提要 上一篇递归算法讲解在这里 递归算法讲解(结合内存图) 没看过的小伙伴可以进去瞅一眼,谢谢! 递归算法的重要性 递归算法是非常重要的,如果想要进大厂,以递归算法为基础的动态规划是必考的&…...
机器学习第33周周报Airformer
文章目录 week33 AirFormer摘要Abstract一、论文的前置知识1. 多头注意力机制(MSA)2. 具有潜变量的变分模型 二、文献阅读1. 题目2. abstract3. 问题与模型阐述3.1 问题定义3.2 模型概述3.3 跨空间MSA(DS-MSA)3.4 时间相关MSA&…...
设计模式(12):代理模式
一.核心作用 通过代理,控制对对象的访问;可以详细控制访问某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。 二.核心角色 抽象角色: 定义代理角色和真实角色的公共对外方法;真实角色: 实现抽…...
前端9种图片格式基础知识, 你应该知道的
彩色深度 彩色深度标准通常有以下几种: 8位色,每个像素所能显示的彩色数为2的8次方,即256种颜色。16位增强色,16位彩色,每个像素所能显示的彩色数为2的16次方,即65536种颜色。24位真彩色,每个…...
ChatGPT 与 OpenAI 的现代生成式 AI(上)
原文:Modern Generative AI with ChatGPT and OpenAI Models 译者:飞龙 协议:CC BY-NC-SA 4.0 序言 本书以介绍生成式 AI 领域开始,重点是使用机器学习算法创建新的独特数据或内容。它涵盖了生成式 AI 模型的基础知识,…...
全量知识系统 程序详细设计之架构设计:一个信息系统架构
统架构,整体设计分成了三部分--三种方面:信息nformation、系统Syste 原文 以下是对全知系统程序详细设计需要的架构规划的考虑。 全知系统架构是一个信息系统架构,整体设计分成了三部分(三种“方面”):信…...
从零开始:成功进入IT行业的方法与技巧
如今,信息技术(IT)行业成为了就业市场上的热门领域。由于其快速发展和广阔的职业机会,许多人希望能够进入这个行业。然而,对于没有任何相关背景知识的人来说,要成功进入IT行业可能会面临一些挑战。本文将分…...
SpringCloud - 如何本地调试不会注册到线上环境(Nacos)?
问题描述 有时候我们需要本地调试注册到 Nacos 上,但是会影响线上服务的 Feign 请求打到本地导致不通影响了线上业务。 原因分析 一般最传统的解决方案就是修改本地 bootstrap.yml 的 spring.cloud.nacos.discovery.namespace spring:application:name: app-serv…...
1.9 面试经典150题 除自身以外数组的乘积
除自身以外数组的乘积 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法࿰…...
【美团笔试题汇总】2023-09-02-美团春秋招笔试题-三语言题解(CPP/Python/Java)
🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新美团近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢…...
小黑逆向爬虫探索与成长之路:小黑独立破解毛毛租数据加密与解密
前言 有道和招标网的加密入口定位在前面两期做了详细的介绍,本小结将通过简单的关键词搜索定位到加密与解密入口 数据接口寻找与请求 根据响应数据长度,确定数据接口,发现传入的参数需要加密,响应的结果需要解密,后…...
深入浅出 -- 系统架构之微服务架构常见的六种设计模式
面向服务的架构(SOA) 面向服务的架构(SOA)是一种设计方法,也是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的…...
SSM框架学习——SqlSession以及Spring与MyBatis整合
SqlSession以及Spring与MyBatis整合 准备所需要的JAR包 要实现MyBatis与Spring的整合,很明显需要这两个框架的JAR包,但是只是使用这两个框架中所提供的JAR包是不够的,还需要配合其他包使用: Spring的JAR包MyBatis的JAR包Spring…...
6、【单例模式】确保了一个类在程序运行期间只有一个实例
你好,我是程序员雪球 在软件设计中,单例模式是一种常见的设计模式。它确保了一个类在程序运行期间只有一个实例,并提供了全局访问该实例的方式。单例模式在许多场景中都有广泛的应用,例如共享资源管理、数据库连接、日志记录器等…...
vuex插件实现数据共享
vuex插件 vuex是管理多个vue通用的数据的插件.(状态管理工具,状态是数据) 我们对于多个vue文件之间的共同数据,是用props传递,或者对于一个vue实例对象,进行绑定,传参,也是多次传参,多个文件之间,比较麻烦. 但是我们vuex会创建一个公共对象,从这个公共对象上赋值,比较简单易…...
【吊打面试官系列】Redis篇 - 使用过 Redis 分布式锁么,它是什么回事?
大家好,我是锋哥。今天分享关于 【使用过 Redis 分布式锁么,它是什么回事?】面试题,希望对大家有帮助; 使用过 Redis 分布式锁么,它是什么回事? 先拿 setnx 来争抢锁,抢到之后&#…...
DashOJ-8.奇偶统计
题目链接: 题目详情 - 奇偶统计 - DashOJ 思路: (while循环加if分支语句) 巧用死循环 while(1) 然后在里面第一句就判断输入的数字是否等于0 if(x0) ,如果 等于0就直接break跳出循环 或者用 while(cin>>x) 代…...
车源宝微信小程序源码
源码介绍 车源宝微信小程序源码 images — 存放项目图片文件 pages — 存放项目页面相关文件 store — 存放数据接口文件 utils — 存放时间格式化等文件 演示截图 源码下载 https://download.csdn.net/download/huayula/89082980...
“双碳”目标下资源环境中的可计算一般均衡(CGE)模型应用
我国政府承诺在2030年实现“碳达峰”,2060年实现“碳中和”,这就是“双碳”目标。为了实现这一目标就必须应用各种二氧化碳排放量很高技术的替代技术,不仅需要考虑技术上的可靠性,也需要考虑经济上的可行性。可计算一般均衡模型&a…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
