算法训练营Day14

#Java #二叉树层次遍历 #反转二叉树

开源学习资料

二叉树的层次遍历:力扣题目链接

二叉树的层次遍历很好理解:

就是从根结点一层一层地往下遍历(同一层,从左到右):

迭代的方式很好理解:就是依次入队出队。

但是判断条件怎么写?

最需要解决的就是,要把节点依次入队,那要怎么记录这些节点,防止它们丢失。

第一步把根节点先入队,这时候要想让它的左孩子和右孩子入队(如上图),就要在A出队的时候,记录它。

关键的就是在一个节点出队的时候,记录该节点,就能找到它的左右孩子。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> res = new ArrayList<>();public List<List<Integer>> levelOrder(TreeNode root) {if(root == null){return res;}//模拟成一个队列//从根节点开始,依次入队(从左到右)Queue<TreeNode> queue = new LinkedList<>(); //创建一个队列//根节点先入队queue.offer(root);while(!queue.isEmpty()){int len = queue.size();List<Integer> list  = new ArrayList<>();while(len>0){//记录出队的节点TreeNode node = queue.poll();list.add(node.val);if(node.left!=null){//左孩子入队queue.offer(node.left);}if(node.right!=null){//右孩子入队queue.offer(node.right);}len--;}res.add(list);}return res;}
}

用两个while循环,主要是为了满足结果形式,保证每个结果都保存在一个新的集合中。

不然就是这样的(结果不能反映出是层次遍历)

先使用DFS迭代遍历练习以下题目:

二叉树的层序遍历II:力扣题目链接

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/class Solution {List<List<Integer>> res = new LinkedList<>();public List<List<Integer>> levelOrderBottom(TreeNode root) {Queue<TreeNode> que = new LinkedList<>();if(root == null){return res;}//先把根节点入队que.offer(root);while(!que.isEmpty()){List<Integer> list = new ArrayList<>();int size = que.size();//每一层入队出队for(int i =0;i<size;i++){TreeNode node = que.poll();list.add(node.val);if(node.left != null){que.offer(node.left);}if(node.right != null){que.offer(node.right);}}res.add(0,list);}return res;}
}

思路相同,只是用了链表的翻转。

二叉树的右视图:力扣题目链接

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> list = new ArrayList<>();Deque<TreeNode> que = new LinkedList<>();if (root == null) {return list;}que.offer(root);while (!que.isEmpty()) {int levelSize = que.size();for (int i = 0; i < levelSize; i++) {TreeNode node = que.poll();if (node.left != null) {que.offer(node.left);}if (node.right != null) {que.offer(node.right);}//就多一步://只要最右边的:if (i == levelSize - 1) {list.add(node.val);}}}return list;}
}

 这道题就关键的一步:只把最右边的放到结果中!

二叉树的层平均值:力扣题目链接

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。 

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Double> averageOfLevels(TreeNode root) {List<Double> list = new ArrayList<>();Queue<TreeNode> que = new LinkedList<>();if(root==null){return list;}que.offer(root);while(!que.isEmpty()){int size = que.size();Double sum =0.0;for(int i =0 ;i<size;i++){TreeNode node = que.poll();sum+=node.val;if(node.left!=null){que.offer(node.left);}if(node.right!=null){que.offer(node.right);}}Double average = sum/size;list.add(average);}return list;}
}

一层一层计算 !

 N叉树的层序遍历:力扣题目链接

给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。 

/*
// Definition for a Node.
class Node {public int val;public List<Node> children;public Node() {}public Node(int _val) {val = _val;}public Node(int _val, List<Node> _children) {val = _val;children = _children;}
};
*/class Solution {public List<List<Integer>> levelOrder(Node root) {if (root == null) {return new ArrayList<List<Integer>>();}List<List<Integer>> ans = new ArrayList<List<Integer>>();Queue<Node> queue = new ArrayDeque<Node>();queue.offer(root);while (!queue.isEmpty()) {int cnt = queue.size();List<Integer> level = new ArrayList<Integer>();for (int i = 0; i < cnt; ++i) {Node cur = queue.poll();level.add(cur.val);for (Node child : cur.children) {queue.offer(child);}}ans.add(level);}return ans;}
}

在每个树行中找最大值:力扣题目链接

您需要在二叉树的每一行中找到最大的值。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> largestValues(TreeNode root) {if(root == null){return Collections.emptyList();}List<Integer> result = new ArrayList();Queue<TreeNode> queue = new LinkedList();queue.offer(root);while(!queue.isEmpty()){int max = Integer.MIN_VALUE;for(int i = queue.size(); i > 0; i--){TreeNode node = queue.poll();max = Math.max(max, node.val);if(node.left != null) queue.offer(node.left);if(node.right != null) queue.offer(node.right);}result.add(max);}return result;}
}

二叉树的最大深度:力扣题目链接

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

class Solution {public int maxDepth(TreeNode root) {if (root == null)   return 0;//先创建一个队列Queue<TreeNode> que = new LinkedList<>();//利用层次遍历//加入节点que.offer(root);int deep =0;while(!que.isEmpty()){int len = que.size();while(len>0){TreeNode node = que.poll();if(node.left!=null) que.offer(node.left);if(node.right!=null) que.offer(node.right);len--;}deep++;}return deep;}
}

二叉树的最小深度 :力扣题目链接

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int minDepth(TreeNode root) {Queue<TreeNode> que = new LinkedList<>();if(root == null){return 0;}que.offer(root);int deep=0;while(!que.isEmpty()){int size = que.size();deep++;for(int i =0;i<size;i++){TreeNode node = que.poll();if(node.left==null && node.right==null){return deep;}if(node.left!=null){que.offer(node.left);}if(node.right!=null){que.offer(node.right);}}}return deep;}
}

利用层序遍历快速刷完了这几道题,发现基本都是一个模板,只是根据每一个题的要求作出一些改变,大体上还是一模一样的。

体会:在外层while中执行的就是当前位置要做的事情,而内层的for循环/while循环,就为下一层做好准备,而size则是控制每层中的节点。

翻转二叉树:力扣题目链接

翻转一棵二叉树。

力扣示例:

这道题用递归来写:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode invertTree(TreeNode root) {//利用递归//递归出口:if(root == null){return null;}invertTree(root.left);invertTree(root.right);swap(root);return root;}//交换的方法public void swap(TreeNode root){TreeNode temp = root.left;root.left = root.right;root.right = temp;}
}

代码很简单,但是要深刻理解递归!

1.递归的出口

2.方法的返回值

当 root 为 null 时,递归的出口就是返回 null。这是因为在二叉树的递归操作中,每个递归步骤都涉及到对左右子树的处理,而 null 表示一个空节点或者叶子节点的空子树。

在这个具体的情境中,当 invertTree 方法递归到叶子节点的左右子树时,这些子树是空的,因此将它们反转后仍然为空。返回 null 可以告诉上一级递归调用,这个空节点的左右子树已经反转完成。

return root, 是为了在递归结束后返回整个树反转后的根节点。

再来练习一道:


 对称二叉树:力扣题目链接

给定一个二叉树,检查它是否是镜像对称的。 

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isSymmetric(TreeNode root) {if(root == null){return true;}return dfs(root.left,root.right);}boolean dfs(TreeNode left , TreeNode right){//递归结束条件://左右子树都为空if(left == null && right ==null){return true;}//左右节点有一个为空if(left == null || right == null){return false;}//左右节点的值不相等if(left.val != right.val){return false;}return dfs(left.left,right.right) && dfs(left.right,right.left);}
}

这些都是比较简单的递归,思想主要是抓住:

方法的返回值

递归的终止条件

确定递归的单层逻辑

在代码随想录中有对这三部曲的详细概括!即时Review~~~~

我自光芒万丈,

何须他人半点光!

Fighting!

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

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

相关文章

用实例域代替序数

在Java中&#xff0c;枚举类型的ordinal()方法返回枚举常量的序数&#xff08;即其在枚举声明中的位置&#xff09;。在某些情况下&#xff0c;使用实例域&#xff08;instance field&#xff09;代替序数可能更加安全和易读。以下是一个示例&#xff0c;演示如何使用实例域代替…

mysql CREATE DATABASE

DROP DATABASE IF EXISTS zengwenfeng;CREATE DATABASE zengwenfeng DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;USE zengwenfeng; 脚本天天少这些&#xff0c;天天找这段&#xff01;

computed 和 watch 的奇妙世界:让数据驱动你的 Vue 应用(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

TestSSLServer4.exe工具使用方法简单介绍(查SSL的加密版本SSL3或是TLS1.2)

一、工具使用方法介绍 工具使用方法参照&#xff1a;http://www.bolet.org/TestSSLServer/ 全篇英文看不懂&#xff0c;翻译了下&#xff0c;能用到的简单介绍如下&#xff1a; 将下载的TestSSLServer4.exe工具放到桌面上&#xff0c;CMD命令行进入到桌面目录&#xff0c;执…

从 0 开始创建 SpringBoot 项目

从 0 开始创建 SpringBoot 项目 从 0 开始创建 SpringBoot 项目环境准备创建项目项目目录结构及说明编写代码参考 从 0 开始创建 SpringBoot 项目 环境准备 操作系统&#xff1a;Windows 10IDE&#xff1a;IntelliJ IDEA 2023.3.1Java 版本&#xff1a;jdk1.8 工具网盘链接&…

俄罗斯军方计划用 Astra Linux 取代 Windows!

网络安全正在改变全球化的面貌&#xff0c;各国政府为了防范外国的间谍和破坏活动&#xff0c;正积极发展自己的技术。在这一趋势下&#xff0c;俄罗斯军方已经开始用 Linux 发行版 Astra Linux 替换 Windows 系统。 如何提高Linux系统安全性&#xff1f;提升Linux安全的关键策…

垃圾收集器及内存分配

目录 垃圾收集器种类 HotSpot虚拟机所包含的收集器 垃圾收集器部分源码 垃圾收集器后台日志参数说明与配对关系 1、串行垃圾收集器 串行垃圾收集器运行示意图 1&#xff09;、编写测试代码 2&#xff09;、设置垃圾回收为串行收集器 3&#xff09;、启动程序&#xff…

Flink 数据集类型

现实世界中&#xff0c;所有的数据都是以流式的形态产生的&#xff0c;不管是哪里产生的数据&#xff0c;在产生的过程中都是一条条地生成&#xff0c;最后经过了存储和转换处理&#xff0c;形成了各种类型的数据集。如下图所示&#xff0c;根据现实的数据产生方式和数据产生是…

基于JavaWeb+SSM+Vue微信小程序的移动学习平台系统的设计和实现

基于JavaWebSSMVue微信小程序的移动学习平台系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 2 第2章 开发环…

【基础篇】1.1 认识STM32(二)

3.3 VREF/VREF-引脚 VREF和VREF-是STM32中用于提供参考电压的引脚。如下图&#xff1a; VREF引脚可以连接一个单独的外部参考电压&#xff0c;范围在2.0V&#xff5e;VDDA&#xff0c;但不能超过VDDA&#xff0c;否则就超过了模拟器件的最大供电电压。在100引脚的封装中&#…

文件上传自动化测试方案(超详细)

一、概述 【测试地址】&#xff1a;https://pan.baidu.com 【测试工具】&#xff1a;selenium、requests 【脚本语言】&#xff1a;Python 【运行环境】&#xff1a;Windows 百度网盘作为文件存储及分享的平台&#xff0c;核心功能大部分是对文件的操作&#xff0c;如果要…

如何一键打开系统属性,编辑环境变量

常规方法&#xff1a; ①右键此电脑→打开属性 ②在控制面版中→系统与安全→系统 对于以上方法&#xff0c;我的电脑都不行&#xff0c;右键属性没反应&#xff1b;点击系统也没反应&#xff0c;这时打开运行窗口&#xff08;winR&#xff09;→输入sysdm.cpl →就可以直接到…

Linux--Docker容器(最新)

这里写目录标题 安装Docker安装指令配置加速器 Docker简介名词解释作用run命令解读 操作常见命令命令的别名 数据卷简介数据卷命令使用 本地目录挂载问题发现问题解决二级目录二级目录 安装Docker 安装指令 如下文档 https://b11et3un53m.feishu.cn/wiki/Rfocw7ctXij2RBkShcu…

【教3妹学编程-算法题】反转二叉树的奇数层

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 3妹&#xff1a;“你不是真正的快乐&#xff0c; 你的…

开具实习证明:在线实习项目介绍

大数据在线实习项目&#xff0c;是在线上为学生提供实习经验的项目。我们希望能够帮助想要在毕业后从事数据科学类工作的学生更加顺利地适应从教室到职场的转换&#xff1b;也帮助那些在工作中需要处理数据、实现数据价值的其他职能的从业者高效快速地掌握每天都能用起来的数据…

SuperMap iClient3D for Cesium 实现鼠标移动选中模型并显示模型对应字段

SuperMap iClient3D for cesium 实现鼠标移动选中模型并显示模型对应字段 一、实现思路二、数据制作1. 计算出模型中心点并保存到属性表中2. 计算出模型顶部高程3. 模型数据切缓存4. 发布三维服务. 三、代码编写 作者&#xff1a;xkf 一、实现思路 将模型属性数据存储到前端&a…

深度学习环境配置

一、Anaconda安装 下载&#xff1a;从清华大学开源软件镜像下载 镜像网址 出现base即为安装成功&#xff1a; 检查显卡的驱动是否正确安装&#xff1a; &#xff08;GPU可以显示出名称&#xff09; GPU0是集显集成显卡是主板自带的显卡。 GPU1是独显即独立显卡&#xff0c…

[渗透测试学习] Codify - HackTheBox

首先nmap扫描端口 nmap -sV -sC -p- -v --min-rate 1000 10.10.11.239扫出来三个端口&#xff0c;22端口为ssh服务&#xff0c;80端口有http服务&#xff0c;3000端口为nodejs框架 尝试访问下80端口&#xff0c;发现页面重定向 将该域名添加到hosts里 sudo vim /etc/hosts 成…

el-table的复选框占满全格

el-table的复选框格子很小每次点击都点不到&#xff0c;又不想设置行点击&#xff0c;因为每次复制内容都会选中&#xff0c;实现效果是点击el-table的复选框单元格就可以选中 <template><div style"width: 60vw; margin: 10px;"><el-table :data&quo…

Java小案例-RocketMQ的11种消息类型,你知道几种?(延迟消息)

前言 上一节给大家讲了Rocket的顺序消息&#xff0c;这一节和大家聊一下延迟消息&#xff0c;关于顺序消息大家可以点下面这个链接直接看 RocketMQ的延迟消息 延迟消息 延迟消息就是指生产者发送消息之后&#xff0c;消息不会立马被消费&#xff0c;而是等待一定的时间之后…