代码随想录算法训练营 DAY 17 | 110.平衡二叉树 257.二叉树的所有路径 404.左叶子之和

110.平衡二叉树

  • 平衡二叉树的定义:任何节点的左右子树高度差绝对值不超过1 空树也是AVL!

  • 确定遍历顺序:

求高度用后序,求深度用前序。(取决于需不需要从下往上返回结果)

先判断它是不是平衡二叉树 如果是就返回 如果不是就记录一下它的最大高度。

递归函数

  1. 递归函数参数和返回值
int getHeight(TreeNode node)
  1. 确定递归终止条件

如果发现左子树和右子树高度差大于1了,我们直接return -1,告诉上一层已经不是AVL树了

if(node == null) return 0;
  1. 单层递归逻辑

后序遍历:左 右 中

leftHeight = getHeight(node.left); //左
if(leftHeight == -1) return -1;
leftRight = getHeight(node.right); //右
if(rightHeight == -1) return -1;
//能进到这说明属于左右子树AVL的条件,看高度差
if(abs.(leftHeight-rightHeight) > 1)  //中result = -1;
else result = 1 + max(leftHeight, rightHeight);
return result;
  • java代码
class Solution {public int getHeight(TreeNode node) {if(node == null) return 0;int leftHeight = getHeight(node.left);if(leftHeight == -1) return -1;int rightHeight = getHeight(node.right);if(rightHeight == -1) return -1;int result = 0;if(Math.abs(leftHeight - rightHeight) > 1) result = -1;else result = 1 + Math.max(leftHeight, rightHeight);return result;}public boolean isBalanced(TreeNode root) {boolean flag;return flag = getHeight(root) >= 0 ? true : false;}
}

257.二叉树的所有路径

  • 确定遍历顺序

我们只能用前序遍历。只有前序(中左右)先遍历父节点,才能让根节点一路指下去,让父节点指向孩子节点。
在这里插入图片描述

回溯?

  • 其实就是一个回退的过程,与递归结合在一起的。

这条路走到头了,就回退到原来的位置再重新开始走另一条路。

  1. 确定递归函数
void traversal(TreeNode node, List<Integer> path, List<String> result)

path数组记录其中的一条路径,result数组存放所有的结果。

  1. 确定终止条件
if(node.left == null && node.right == null) {result.add(path);  //省略转化逻辑
}

遍历到叶子节点了就停,收获当前结果。

  1. 单层递归逻辑

前序顺序:中左右

我们每遍历到一个节点,就要把这个节点添加进path里。

path.add(node.val);  //中

注意这一句要放在递归函数进来的第一句!不然到叶子节点还没记录就添加结果了

接下来写左 和 右。有没有可能node.left(right)为空也进到下一层递归呢?此时path.add(node.val),结点为空。所以在左右递归之前要先判断是否不为空才遍历。

if(node.left) {traversal(node.left,path,result);path.remove(); //恢复现场 回溯的过程
}
if(node.right) {traversal(node.right,path,result);path.remove();  //恢复现场 回溯的过程
}

有递归,就有回溯!退出递归的时候,表示已经收集到了结果或者遍历完了,此时弹出一个元素恢复现场。

这题我们设定是到叶子节点就停下来,不要让空节点进入到递归!所以可以在第一句就add,然后往左右递归之前也要判断是否左右孩子为空

list

  • 完整java代码
class Solution {public void traversal(TreeNode node, List<Integer> path, List<String> res) {path.add(node.val);  //这一句实际就是处理“中”的逻辑if(node.left == null && node.right == null) {  //遇到了叶子节点就收集StringBuilder sb = new StringBuilder();for(int i = 0; i < path.size()-1; i++) {  //在前n-1个数字后面拼上个"->"sb.append(path.get(i));sb.append("->");}sb.append(path.get(path.size()-1));  //把最后一个数字拼上去res.add(sb.toString());  //收集这一条路径return;  //一直收集到叶子节点才会返回!}//递归遍历左和右 记得判断不为空+回溯恢复现场if(node.left != null) {traversal(node.left, path, res);path.remove(path.size()-1);}if(node.right != null) {traversal(node.right, path, res);path.remove(path.size()-1);}}public List<String> binaryTreePaths(TreeNode root) {List<Integer> path = new ArrayList<>();List<String> res = new ArrayList<>();traversal(root,path,res);return res;}
}

404.左叶子之和

左叶子?

首先一定是个叶子节点(左右孩子都为空),其次一定是它父节点的左孩子!(根节点一定不是)

之前的题目,我们都是遍历到一个元素,才判断这个元素是不是符合的 我们要进行收集,但是这题不一样!

判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。

遍历顺序

用后序比较简洁,因为要一层一层向上返回。父节点只要把左子树的左叶子和 与 右子树的左叶子和相加就行。

递归函数

  1. 递归函数
int traversal(TreeNode node)
  1. 终止条件
if(node == null) return 0;
if(node.left == null && node.right == null) {  //只是遇到叶子节点return 0;
}

遇到叶子节点也要return 0(因为它的左子树和右子树都没有左叶子之和)

  1. 单层逻辑
int leftSum = traversal(node.left);  //收集左子树里的左叶子和
if(node.left != null && node.left.left == null && node.left.right == null)  //如果左孩子不为空 且左孩子是叶子节点leftSum = node.left.val;  //收集
int rightSum = traversal(node.right);  //收集右子树里的左叶子和
return leftSum + rightSum;  //中
  • 完整代码
class Solution {public int traversal(TreeNode node) {if(node == null) return 0;if(node.left == null && node.right == null) return 0; //叶子节点的左右子树 左叶子和为0int leftSum = traversal(node.left);  //收集左子树里的左叶子和if(node.left != null && node.left.left == null && node.left.right == null)  //如果左孩子不为空 且左孩子是叶子节点leftSum = node.left.val;  //收集int rightSum = traversal(node.right);  //收集右子树里的左叶子和return leftSum + rightSum;  //中}public int sumOfLeftLeaves(TreeNode root) {return traversal(root);}
}

理解这两个递归终止条件!不是为了收集值服务的,是为了终止递归。

day17总结

  1. List可以用list.get(i)获取第i个元素

    List用list.remove(i)删除第i个元素

    List长度是list.size()

  2. StringBuilder转换为String用sb.toString()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/763613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CVTE 一面凉经Ⅰ】循环依赖如何解决

目录 一.&#x1f981; 开始前的废话二. &#x1f981; 什么是循环依赖&#xff1f;三. &#x1f981;Spring 容器解决循环依赖的原理是什么?五. &#x1f981; 三级缓存解决循环依赖的原理六. &#x1f981; 由有参构造方法注入属性的循环依赖如何解决&#xff1f;七.&#x…

vue3通过el-cascader实现动态菜单切换页面

如果只有一级菜单只会显示一个按钮 <div style"width: 100%; margin-top: 10px; display: flex; align-items: center; border-bottom: 1px solid #ccc;"><template v-for"(menu, index) in cascaderData" :key"index"><el-casc…

整数和浮点数在内存中存储

整数在内存中的存储 整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码。 对于整形来说&#xff0c;数据存放内存中的其实是补码。 在计算机系统中&#xff0c;数值一律用补码来表示和存储。原因是&#xff0c;使用补码&#xff0c;可以使符号位和数值域统一处理&am…

DUSt3R:简化三维重建

3D 重建是从二维 (2D) 图像创建对象或场景的 3D 虚拟表示的任务&#xff0c;可用于模拟、可视化或本地化等多种目的。 它广泛应用于计算机视觉、机器人和虚拟现实&#xff08;VR&#xff09;等多个领域。 在基本设置中&#xff0c;3D 重建方法输入一对图像 I1 和 I2&#xff0c…

关于Java对接网络验证+实践小例子,简单易懂

一个简单的网络验证小例子&#xff0c;各位大佬勿喷 突发奇想&#xff0c;如果一位A友找你拿一份 Working Fruits&#xff0c;但是你不想这位A友把你辛苦劳作、熬夜加点写出的代码分享他或她的另外一位朋友B友&#xff0c;也许并不是很有价值的一个小作业而已&#xff0c;但是就…

数据结构:详解【栈和队列】的实现

目录 1. 栈1.1 栈的概念及结构1.2 栈的实现1.3 栈的功能1.4 栈的功能的实现1.5 完整代码 2. 队列2.1 队列的概念及结构2.2 队列的实现2.3 队列的功能2.4 队列的功能的实现2.5 完整代码 1. 栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的…

模拟B\S服务器(扩展知识点)

3.2 模拟B\S服务器(扩展知识点) 模拟网站服务器&#xff0c;使用浏览器访问自己编写的服务端程序&#xff0c;查看网页效果。 案例分析 准备页面数据&#xff0c;web文件夹。 复制到我们Module中&#xff0c;比如复制到day08中 我们模拟服务器端&#xff0c;ServerSocket类…

SpringCloud Alibaba实战和源码(8)OpenFeign使用

1、 使用Feign实现远程HTTP调用 1.1、常见HTTP客户端 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协 议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 J…

RN开发搬砖经验之—处理“Duplicate class com.github.barteksc.pdfviewer“

问题信息 Duplicate class com.github.barteksc.pdfviewer.PDFView found in modules jetified-AndroidPdfViewer-3.1.0-beta.3-runtime (com.github.TalbotGooday:AndroidPdfViewer:3.1.0-beta.3) and jetified-android-pdf-viewer-2.8.2-runtime (com.github.barteksc:andro…

为车主提供多路况安全保障!“北欧轮胎安全专家”熊牌轮胎迎来全新升级

德国马牌轮胎旗下明星品牌——Gislaved熊牌轮胎迎来全新升级。 自进入中国市场以来&#xff0c;熊牌轮胎凭借着坚韧安全、静音降噪等特点&#xff0c;收获无数好评。此次全新升级的熊牌轮胎&#xff0c;在品牌logo中加入了“北欧棕熊”的形象&#xff0c;并且对此前轮胎标签中的…

qt使用Windows经典风格,以使QTreeView或QTreeWidge有节点线或加号

没有使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 树展开时&#xff1a; 树未展开时&#xff1a; 可以看到&#xff1a; 未使用Windows经典风格时&#xff0c;QTreeView或QTreeWidget…

【MySQL】基本查询(1)

【MySQL】基本查询&#xff08;1&#xff09; 目录 【MySQL】基本查询&#xff08;1&#xff09;表的增删改查Create单行数据 全列插入多行数据 指定列插入插入否则更新替换 RetrieveSELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不…

第六篇:视频广告格式上传指南(上) - IAB视频广告标准《数字视频和有线电视广告格式指南》

第六篇&#xff1a; 视频广告格式和上传指南&#xff08;上&#xff09; --- 我为什么要翻译介绍美国人工智能科技公司IAB系列技术标准&#xff08;2&#xff09; 流媒体数字视频的广告格式分为线性和非线性两大类。任何一个广告都可以与显示在视频播放器外部的伴随横幅一起提…

【Linux文件系列】重定向

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CMake学习(下)

1. 嵌套的CMake 如果项目很大&#xff0c;或者项目中有很多的源码目录&#xff0c;在通过CMake管理项目的时候如果只使用一个CMakeLists.txt&#xff0c;那么这个文件相对会比较复杂&#xff0c;有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件&#xff…

windows系统下python进程管理系统

两年来&#xff0c;我们项目的爬虫代码大部分都是放在公司的windows机器上运行的&#xff0c;原因是服务器太贵&#xff0c;没有那么多资源&#xff0c;而windows主机却有很多用不上。为了合理利用公司资源&#xff0c;降低数据采集成本&#xff0c;我在所以任务机器上使用anac…

将本地的项目上传到gitee,

场景&#xff1a;在本地有一个项目&#xff0c;想要把这个项目上传到gitee&#xff0c;且在gitee中已经创建好仓库 依次执行下图中的命令&#xff1a;

【linux】进程地址空间(进程三)

目录 快速了解&#xff1a;引入最基本的理解&#xff1a;细节&#xff1a;如何理解地址空间&#xff1a;a.什么是划分区域&#xff1a;b.地址空间的理解&#xff1a; 为什么要有进程空间&#xff1f;进一步理解页表与写时拷贝&#xff1a; 快速了解&#xff1a; 先来看这样一段…

2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作…

第四范式2023全年业绩:营收人民币42.0亿元同比增长36.4%,行业大模型为千行万业赋能...

3月20日&#xff0c;第四范式&#xff08;06682.HK&#xff09;公布2023年全年业绩&#xff0c;营收稳步增长&#xff0c;盈利节奏清晰。 第四范式定位人工智能时代的软件企业&#xff0c;致力于用人工智能技术赋能千行万业&#xff0c;帮助各行业发现更多规律&#xff0c;形成…