【代码随想录刷题】Day18 二叉树05

文章目录
- 1.【513】找树左下角的值
- 1.1题目描述
- 1.2 解题思路
- 1.2.1 迭代法思路
- 1.2.2 递归法思路
- 1.3 java代码实现
- 1.3.1 迭代法java代码实现
- 1.3.2 递归法java代码实现
- 2. 【112】路径总和
- 2.1题目描述
- 2.2 解题思路
- 2.3 java代码实现
- 3.【106】从中序与后序遍历序列构造二叉树
- 3.1题目描述
- 3.2 解题思路
- 3.3 java代码实现
【513】找树左下角的值
【112】路径总和
【106】从中序与后序遍历序列构造二叉树
1.【513】找树左下角的值
1.1题目描述
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。

提示:
- 二叉树的节点个数的范围是 [1,104]
- -231 <= Node.val <= 231 - 1
1.2 解题思路
1.2.1 迭代法思路
本题要找出树的最后一行的最左边的值,使用层序遍历是非常简单的,只需要记录最后一行第一个节点的数值就可以了。
1.2.2 递归法思路
题目:在树的最后一行找到最左边的值。
首先要是最后一行,然后是最左边的值。
如果使用递归法,如何判断是最后一行呢?其实就是深度最大的叶子节点一定是最后一行。所以要找深度最大的叶子节点。
那么如何找最左边的呢?可以使用前序遍历(当然中序,后序都可以,因为本题没有 根节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
递归三部曲
-
- 确定递归函数的参数和返回值
参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。
本题还需要类里的两个全局变量,maxDepth用来记录最大深度,result记录最大深度最左节点的数值。
int result;// 全局变量 记录最大深度int maxDepth=-1;// 全局变量 最大深度最左节点的数值public void traversal(TreeNode root,int depth)
-
- 确定终止条件
当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
if (root.left==null && root.right==null){if (depth>maxDepth){maxDepth=depth;// 更新最大深度result=root.val;// 最大深度最左面的数值}return;}
-
- 确定单层递归的逻辑
在找最大深度的时候,递归的过程中依然要使用回溯
if (root.left!=null){//左depth++;traversal(root.left,depth);//回溯depth--;}if (root.right!=null){//右depth++;traversal(root.right,depth);//回溯depth--;}return;
1.3 java代码实现
1.3.1 迭代法java代码实现
class Solution {public int findBottomLeftValue(TreeNode root) {//迭代法 层次遍历Queue<TreeNode> que=new LinkedList<>();que.offer(root);int res=0;while (!que.isEmpty()){int len=que.size();for (int i = 0; i < len; i++) {TreeNode tempNode=que.poll();// 记录最后一行第一个元素if (i==0){res=tempNode.val;}if (tempNode.left!=null){que.offer(tempNode.left);}if (tempNode.right!=null){que.offer(tempNode.right);}}}return res;}
}
1.3.2 递归法java代码实现
class Solution {int result;// 全局变量 记录最大深度int maxDepth=-1;// 全局变量 最大深度最左节点的数值public int findBottomLeftValue(TreeNode root) {//递归traversal(root,0);return result;}public void traversal(TreeNode root,int depth){if (root.left==null && root.right==null){if (depth>maxDepth){maxDepth=depth;// 更新最大深度result=root.val;// 最大深度最左面的数值}return;}if (root.left!=null){//左depth++;traversal(root.left,depth);//回溯depth--;}if (root.right!=null){//右depth++;traversal(root.right,depth);//回溯depth--;}return;}
}
递归函数简写:
public void traversal(TreeNode root,int depth){if (root.left==null && root.right==null){if (depth>maxDepth){maxDepth=depth;// 更新最大深度result=root.val;// 最大深度最左面的数值}return;}if (root.left!=null){//左traversal(root.left,depth+1);// 隐藏着回溯}if (root.right!=null){//右traversal(root.right,depth+1);// 隐藏着回溯}return;}
2. 【112】路径总和
2.1题目描述
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。

提示:
- 树中节点的数目在范围 [0, 5000] 内
- -1000 <= Node.val <= 1000
- -1000 <= targetSum <= 1000
2.2 解题思路
本题可以采用深度遍历的方式来遍历(本题前中后序都可以,无所谓,因为根节点也没有处理逻辑)。,递归法

2.3 java代码实现
class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {if (root==null){return false;}targetSum -= root.val;//叶子结点if (root.left==null && root.right==null){return targetSum==0;}if (root.left!=null){boolean left=hasPathSum(root.left,targetSum);//已经找到if (left){return true;}}if (root.right!=null){boolean right=hasPathSum(root.right,targetSum);//已经找到if (right){return true;}}return false;}
}
3.【106】从中序与后序遍历序列构造二叉树
3.1题目描述
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

提示:
- 1 <= inorder.length <= 3000
- postorder.length == inorder.length
- -3000 <= inorder[i], postorder[i] <= 3000
- inorder 和 postorder 都由 不同 的值组成
- postorder 中每一个值都在 inorder 中
- inorder 保证是树的中序遍历
- postorder 保证是树的后序遍历
3.2 解题思路
中序遍历与后序遍历构造二叉树的理论知识
以 后续数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后续数组。一层一层的切下去,每次后续数组的最后一个元素就是节点元素。
流程如下:

代码该怎样写呢?提到一层一层切割,就应该想到了递归
-
- 如果数组大小为0的话,说明是空节点了
-
- 如果不为空,那么取后序数组的最后一个元素作为节点元素
-
- 找到后序数组最后一个元素在中序数组中的位置,作为切割点
-
- 切割中序数组,切成中序左数组和中序右数组(顺序一定不能弄反了,一定要先切中序数组)
-
- 切割后序数组,切成后序左数组和后序右数组
-
- 递归处理左区间和右区间
3.3 java代码实现
class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {if (postorder.length==0 || inorder.length==0){return null;}return buildHelper(inorder,0,inorder.length,postorder,0, postorder.length);}public TreeNode buildHelper(int[] inorder,int inorderBegin,int inorderEnd,int[] postorder,int postBegin,int postEnd){if (postBegin==postEnd){return null;}//根节点int rootVal=postorder[postEnd-1];TreeNode root=new TreeNode(rootVal);//切割点int middleIndex;for (middleIndex=inorderBegin;middleIndex<inorderEnd;middleIndex++){if (inorder[middleIndex]==rootVal){break;}}//切割中序数组//左中序数组,左闭右开[leftInorderBegin,leftInoderEnd)int leftInorderBegin=inorderBegin;int leftInoderEnd=middleIndex;//右中序数组,左闭右开[rightInorderBegin,leftInoderEnd)int rightInorderBegin=middleIndex+1;int rightInoderEnd=inorderEnd;//切割后序数组//左后序数组,左闭右开[leftPostorderBegin,leftPostoderEnd)int leftPostorderBegin=postBegin;//终止位置是 需要加上 中序区间的大小sizeint leftPostoderEnd=postBegin+(middleIndex-inorderBegin);//右后序数组,左闭右开[rightPostorderBegin,leftPostoderEnd)int rightPostorderBegin=leftPostoderEnd;int rightPostoderEnd=postEnd-1;//排除最后一个元素,已经作为节点了root.left=buildHelper(inorder,leftInorderBegin,leftInoderEnd,postorder,leftPostorderBegin,leftPostoderEnd);root.right=buildHelper(inorder,rightInorderBegin,rightInoderEnd,postorder,leftPostorderBegin,rightPostoderEnd);return root;}
}
class Solution {Map<Integer,Integer> map;//方便根据数值查找位置public TreeNode buildTree(int[] inorder, int[] postorder) {map=new HashMap<>();// 用map保存中序序列的数值对应位置for (int i=0;i<inorder.length;i++){map.put(inorder[i],i );}return findNode(inorder,0,inorder.length,postorder,0,postorder.length);}public TreeNode findNode(int[] inorder,int inorderBegin,int inorderEnd,int[] postorder,int postBegin,int postEnd){//参数里的范围都是左闭右开if (inorderBegin>=inorderEnd || postBegin>=postEnd){return null;}// 找到后序遍历的最后一个元素在中序遍历中的位置int rootIndex=map.get(postorder[postEnd-1]);TreeNode root=new TreeNode(inorder[rootIndex]);//构造节点//保存中序左子树个数,用来确定后序数列的个数int lenOfleft=rootIndex-inorderBegin;root.left=findNode(inorder,inorderBegin,rootIndex,postorder,postBegin,postBegin+lenOfleft);root.right=findNode(inorder,rootIndex+1,inorderEnd,postorder,postBegin+lenOfleft,postEnd-1);return root;}}
相关文章:
【代码随想录刷题】Day18 二叉树05
文章目录 1.【513】找树左下角的值1.1题目描述1.2 解题思路1.2.1 迭代法思路1.2.2 递归法思路 1.3 java代码实现1.3.1 迭代法java代码实现1.3.2 递归法java代码实现 2. 【112】路径总和2.1题目描述2.2 解题思路2.3 java代码实现 3.【106】从中序与后序遍历序列构造二叉树3.1题目…...
2023.11.25更新关于mac开发APP(flutter)的笔记与整理(实机开发一)
我自己写的笔记很杂,下面的笔记是我在chatgpt4的帮助下完成的,希望可以帮到正在踩坑mac开发APP(flutter)的小伙伴 目标:通过MAC电脑使用flutter框架开发一款适用于苹果手机的一个APP应用 本博客的阅读顺序是…...
万宾科技可燃气体监测仪的功能有哪些?
随着城市人口的持续增长和智慧城市不断发展,燃气作为一种重要的能源供应方式,已经广泛地应用于居民生活和工业生产的各个领域。然而燃气泄漏和安全事故的风险也随之增加,对城市的安全和社会的稳定构成了潜在的威胁。我国燃气管道安全事故的频…...
Binlog vs. Redo Log:数据库日志的较劲【高级】
🎏:你只管努力,剩下的交给时间 🏠 :小破站 Binlog vs. Redo Log:数据库日志的较劲【高级】 前言第一:事务的生命周期事务的生命周期Binlog和Redo Log记录事务的一致性和持久性Binlog的记录过程R…...
移动机器人路径规划(二)--- 图搜索基础,Dijkstra,A*,JPS
目录 1 图搜索基础 1.1 机器人规划的配置空间 Configuration Space 1.2 图搜索算法的基本概念 1.3 启发式的搜索算法 Heuristic search 2 A* Dijkstra算法 2.1 Dijkstra算法 2.2 A*&&Weighted A*算法 2.3 A* 算法的工程实践中的应用 3 JPS 1 图搜索基础 1.1…...
消息中间件——RabbitMQ(四)命令行与管控台的基本操作!
前言 在前面的文章中我们介绍过RabbitMQ的搭建:RabbitMQ的安装过以及各大主流消息中间件的对比:,本章就主要来介绍下我们之前安装的管控台是如何使用以及如何通过命令行进行操作。 1. 命令行操作 1.1 基础服务的命令操作 rabbitmqctl sto…...
性能压测工具:wrk
一般我们压测的时候,需要了解衡量系统性能的一些参数指标,比如。 1、性能指标简介 1.1 延迟 简单易懂。green:一般指响应时间 95线:P95。平均100%的请求中95%已经响应的时间 99线:P99。平均100%的请求中99%已经响应的时间 平…...
[Matlab有限元分析] 2.杆单元有限元分析
1. 一维杆单元有限元分析程序 一维刚单元的局部坐标系(单元坐标系)与全局坐标系相同。 1.1 线性杆单元 如图所示是一个杆单元,由两个节点i和j,局部坐标系的X轴沿着杆的方向,由i节点指向j节点,每个节点有…...
透过对话聊天聊网络tcp三次握手四次挥手
序 说起来网络,就让我想起的就是一张图。我在网上可以为所欲为,反正你又不能顺着网线来打我。接下来我们来详细说一下网络到底是怎么连接的。 TCP三次打招呼 首先我会用男女生之间的聊天方式,来举一个例子。 从tcp三次握手来说,…...
项目管理套路:看这一篇绝对够用❤️
写论文必不可少的,就是创建代码并进行实验。好的项目管理可以让实验进行得更加顺利。本篇博客以一次项目实践为例,介绍项目管理的方法,以及可能遇到的问题,并提供一些可行的解决方案。 目录 项目管理工具开始第一步版本管理十分关…...
华为-算法---测试开发工程师----摘要牛客网
Java面试题---摘要牛客网-CSDN博客package extendNiuKeWang;import java.util.Scanner;public class GoodHuaWei {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int money = sc.nextInt();System.out.println("n值总金额:"+money)…...
python环境搭建-yolo代码跑通-呕心沥血制作(告别报错no module named torch)
安装软件 安装过的可以查看有没有添加环境变量 好的! 我们发车! 如果你想方便快捷的跑通大型项目,那么必须安装以下两个软件: 1.pycharm2.anaconda对应作用: pycharm:专门用来跑通python项目的软件,相当于一个编辑器,可以debug调试,可以接受远程链接调试!anaconda:专…...
Cisco Packet Tracer配置命令——路由器篇
路由基础 路由器用于互联两个或多个网络,具有两项功能:为要转发的数据包选择最佳路径以及将数据包交换到正确的端口,概括为路由选择和分组转发。 路由选择 路由选择就是路由器根据目的IP地址的网络地址部分,通过路由选择算法确…...
setContentsMargins(QMargins()) 是 QWidget 类的成员函数,用于设置小部件的内容边距(Contents Margins)
setContentsMargins(QMargins()) 是 QWidget 类的成员函数,用于设置小部件的内容边距(Contents Margins)。 在 Qt 中,内容边距指的是小部件内部内容与小部件边界之间的空白区域。通过设置内容边距,可以控制和调整小部…...
Redis key 过期监听实现
1.技术背景,想知道 redis 设置了TTL时间的key 过期,且有后续的业务处理的场景可以使用。 bug点: 使用redis 缓存失效监听会有一定的延迟, 过期事件是在redis服务器删除键的时候生成的,而不是在理论上生存时间到达0值得…...
Gee教程2.上下文Context
先来看看Gin框架的简单例子 func main() {engine : gin.Default()engine.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "hello World!")})//监听并启动服务,默认 http://localhost:8080/engine.Run() }//我们自己写的 func main()…...
【从浅识到熟知Linux】基本指定之cat、more和less
🎈归属专栏:从浅学到熟知Linux 🚗个人主页:Jammingpro 🐟每日一句:写完这篇我要去吃晚饭啦!! 文章前言:本文介绍cat、more和less指令三种查看文件的用法并给出示例和截图…...
2018年7月24日 Go生态洞察:Go Cloud实现便携式云编程
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
storyBook常见踩坑报错 和 解决
用StoryBook官网的代码,但报错,Unexpected token’<’ 在js文件中// Button.stories.js|jsx import { Button } from ‘./Button’; export default { component: Button, }; /* *👇 Render functions are a framework specific featur…...
python 笔记 根据用户轨迹+基站位置,估计基站轨迹+RSRP
1 问题描述 已知用户实际的轨迹,和基站的位置,能不能得到用户所连接的基站,以及基站的信号强度RSRP? 1.1 几个假设 这里我们做几个假设: 每个用户有80%的概率连接最近的基站,有20%的概率选择其他的基站连…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
