二叉树BFS

前置知识

二叉树节点的定义

  • 二叉树是递归定义的
/*** Definition for a binary tree node.(LeetCode)*/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;}
}

广度优先遍历搜索 Breath First Search (BFS)

BFS

  • BFS通常需要使用一个队列来维护搜索过程。
  • 先进先出 First In First Out (FIFO)。

层序遍历 Level-order Traverse

  • 树的广度优先遍历亦可称为层序遍历。
  • 从上到下、从左到右访问树中的节点,每一层的节点都按顺序出现。
    层序遍历

多源BFS

单源BFS:从某一个点开始(一个起点)。
多源BFS:从多个点同时开始走(多个起点)。

二叉树结构

LeetCode 2236. 判断根结点是否等于子结点之和

  • 比较二叉树根节点的值val、左子树left和右子树right节点的值之和
class Solution {public boolean checkTree(TreeNode root) {if( root.val == root.left.val + root.right.val )return true;elsereturn false;}
}

二叉树的层序遍历

LeetCode 102. 二叉树的层序遍历

  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {// 遍历结果,注意题目输出格式List<List<Integer>> traverseResult  = new LinkedList<>();// 根节点为空的情况if ( root == null )return traverseResult;// BFS,使用队列Queue<TreeNode> queue = new LinkedList<>();// 前面判断了根节点为空,这里根节点入队列queue.add(root);// 借助队列层序遍历二叉树,直到所有节点出列while( !queue.isEmpty() ) {// 每层节点个数int levelCount = queue.size();// 该层每个节点值List<Integer> levelResult = new ArrayList<>();// 遍历该层节点for (int i=0; i<levelCount; i++) {// 队头节点出队列TreeNode node = queue.poll();// 出列节点值,加入List集合levelResult.add(node.val);// 左节点存在,入队if ( node.left != null ) {queue.add( node.left );}// 右节点存在,入队if ( node.right != null ) {queue.add( node.right );}}// 该层遍历结果traverseResult.add( levelResult );}return traverseResult;}
}

LeetCode 107. 二叉树的层序遍历 II

  • BFS层序遍历,在遍历完一层节点之后,将存储该层节点值的列表添加到结果列表的头部。
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<List<Integer>> levelOrderBottom(TreeNode root) {// 遍历结果,注意题目输出格式、自底向上List<List<Integer>> traverseResult = new LinkedList<>();// 根节点为空的情况if ( root == null )return traverseResult;// BFS,使用队列Queue<TreeNode> queue = new LinkedList<>();// 前面判断了根节点为空,这里根节点入队列queue.add(root);// 借助队列层序遍历二叉树,直到所有节点出列while( !queue.isEmpty() ) {// 每层节点个数int levelCount = queue.size();// 该层每个节点值List<Integer> levelResult = new ArrayList<>();// 遍历该层节点for ( int i=0; i<levelCount; i++ ) {// 队头节点出队列TreeNode node = queue.poll();// 出列节点值,加入List集合levelResult.add(node.val);// 左节点存在,入队if ( node.left != null )queue.add(node.left);// 右节点存在,入队if ( node.right != null )queue.add(node.right);}// 该层遍历结果,将存储该层节点值的列表添加到结果列表的头部。traverseResult.add(0,levelResult);}return traverseResult;}
}

LeetCode 103. 二叉树的锯齿形层序遍历

  • BFS层序遍历,利用双端队列交替顺序输出每层结果。
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {List<List<Integer>> traverseResult = new LinkedList<>();if ( root == null )return traverseResult;// BFS层序遍历,双端队列实现输出顺序交替Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);// true时从左往右,false时从右往左boolean flag = true;while( !queue.isEmpty() ) {int levelCount = queue.size();// 双端队列LinkedList<Integer> levelResult = new LinkedList<>();for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();// 从左往右,插入双端队列末尾if(flag)levelResult.offerLast(node.val);// 从右往左,插入双端队列头部elselevelResult.offerFirst(node.val);if ( node.left != null)queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}traverseResult.add(levelResult);// 每层遍历完,修改标记flag = !flag;}return traverseResult;}
}

LeetCode 637. 二叉树的层平均值

  • BFS,层平均值 = 每层节点值之和 / 每层节点数量
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<Double> averageOfLevels(TreeNode root) {List<Double> avgResult = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while( !queue.isEmpty() ) {int levelCount = queue.size();double levelSum = 0;for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();levelSum += node.val;if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}avgResult.add( levelSum / levelCount );}return avgResult;}
}

LeetCode 199. 二叉树的右视图

  • BFS,记录下每层的最后一个元素。
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> rightResult = new ArrayList<>();if ( root == null )return rightResult;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while ( !queue.isEmpty() ) {int levelCount = queue.size();for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();// 每层最右侧节点if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);if (i+1 == levelCount)rightResult.add(node.val);}}return rightResult;}
}

LeetCode 513. 找树左下角的值

  • BFS层序遍历,最后更新的值,是最后一层最左节点值。
  • 注意节点值的数据范围, − 2 31 < = N o d e . v a l < = 2 31 − 1 -2^{31} <= Node.val <= 2^{31} - 1 231<=Node.val<=2311
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int bottomLeft = root.val;while ( !queue.isEmpty() ) {int levelCount = queue.size();for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();// 每层最左边节点的值if ( i == 0 )bottomLeft = node.val;if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}}// 层序遍历,bottomLeft是最后一层最左边节点的值return bottomLeft;}
}

LeetCode 515. 在每个树行中找最大值

  • BFS层序遍历,取每层全部节点中的最大值。
  • 注意节点值的数据范围, − 2 31 < = N o d e . v a l < = 2 31 − 1 -2^{31} <= Node.val <= 2^{31} - 1 231<=Node.val<=2311
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public List<Integer> largestValues(TreeNode root) {List<Integer> largestResult = new LinkedList<>();if ( root == null )return largestResult;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while ( !queue.isEmpty() ) {int levelCount = queue.size();int maxValue = Integer.MIN_VALUE;for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();if ( maxValue < node.val )maxValue = node.val;if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}largestResult.add(maxValue);}return largestResult;}
}

LeetCode 1161. 最大层内元素和

  • BFS层序遍历,累加每层元素之和,记录和最大的层号。
  • 注意节点值的数据范围, − 1 0 5 < = N o d e . v a l < = 1 0 5 -10^{5} <= Node.val <= 10^{5} 105<=Node.val<=105
  • 注意变量赋值位置,是否受循环影响(代码思路没错,卡在这个细节好久,最后发现是这里的问题)
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public int maxLevelSum(TreeNode root) {int maxLevel = 1;int maxSum = Integer.MIN_VALUE;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int level = 1;while ( !queue.isEmpty() ) {int levelCount = queue.size();int levelSum = 0;for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();levelSum += node.val;if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}if ( levelSum > maxSum ) {maxLevel = level;maxSum = levelSum;}level += 1;}return maxLevel;}
}

LeetCode 101. 对称二叉树

  • 更适合用深度优先遍历搜索DFS解这道题。
  • BFS层序遍历,每层从左往右、从右往左的结果是否相等。
  • 注意空节点缺省值填充。
  • 注意节点值的数据范围, − 100 < = N o d e . v a l < = 100 -100 <= Node.val <= 100 100<=Node.val<=100
  • 时间复杂度O(n)
  • 空间复杂度O(n)
class Solution {public boolean isSymmetric(TreeNode root) {// BFS做法if ( root == null )return true;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while( !queue.isEmpty() ) {int levelCount = queue.size();LinkedList<Integer> leftResult = new LinkedList<>();LinkedList<Integer> rightResult = new LinkedList<>();// 每层循环遍历,从左往右、从右往左的结果是否相等for(int i=0; i<levelCount; i++) {TreeNode node = queue.poll();// 节点值范围 -100 ~ 100,空节点可用极大或极小值填充if ( node == null ) {leftResult.offerLast(-1000);rightResult.offerFirst(-1000);}else {leftResult.offerLast(node.val);rightResult.offerFirst(node.val);queue.offer(node.left);queue.offer(node.right);}}// 每层从左往右、从右往左的结果是否相等,空节点用缺省值填充if (leftResult.equals(rightResult))continue;elsereturn false;}return true;}
}

LeetCode 1302. 层数最深叶子节点的和

  • BFS,保留最后一层所有节点值的和。
class Solution {public int deepestLeavesSum(TreeNode root) {int sumResult = 0;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while( !queue.isEmpty() ) {int levelCount = queue.size();int levelSum = 0;for ( int i=0; i<levelCount; i++ ) {TreeNode node = queue.poll();levelSum += node.val;if ( node.left != null )queue.offer(node.left);if ( node.right != null )queue.offer(node.right);}sumResult = levelSum;}return sumResult;}
}

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

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

相关文章

【java爬虫】获取个股详细数据并用echarts展示

前言 前面一篇文章介绍了获取个股数据的方法&#xff0c;本文将会对获取的接口进行一些优化&#xff0c;并且添加查询数据的接口&#xff0c;并且基于后端返回数据编写一个前端页面对数据进行展示。 具体的获取个股数据的接口可以看上一篇文章 【java爬虫】基于springbootjd…

Android : 使用GestureOverlayView进行手势识别—简单应用

示例图&#xff1a; GestureOverlayView介绍&#xff1a; GestureOverlayView 是 Android 开发中用于识别和显示手势的视图组件。它允许用户在屏幕上绘制手势&#xff0c;并且应用程序可以检测和响应这些手势。以下是关于 GestureOverlayView 的主要特点&#xff1a; 手势识别…

nodejs+vue+微信小程序+python+PHP特困救助供养信息管理系统-计算机毕业设计推荐

通过走访某特困救助供养机构实际情况&#xff0c;整理特困救助供养机构管理的业务流程&#xff0c;分析当前特困救助供养机构管理存在的各种问题&#xff0c;利用软件开发思想对特困救助供养机构特困救助供养机构管理进行系统设计分析。通过服务端程序框架进行设计&#xff0c;…

MFC - 给系统菜单(About Dialog)发消息

文章目录 MFC - 给系统菜单(About Dialog)发消息概述笔记resource.h菜单的建立菜单项的处理MSDN上关于系统菜单项值的说法END MFC - 给系统菜单(About Dialog)发消息 概述 做了一个对话框程序, 在系统菜单(在程序上面的标题栏右击)中有"关于"的菜单. 这个是程序框架…

【MySQL】事务Transaction

1. 事务的概念 事务是什么 在业务逻辑中使用sql&#xff0c;面对一些较复杂的场景&#xff0c;是需要多个sql语句组合起来实现的。如&#xff1a;银行的转账业务&#xff0c;若客户A要转账100元给客户B&#xff0c;就要两条sql&#xff1a;A余额减100&#xff0c;B余额加100&a…

ES6语法(五)封装模块化公共工具函数、引入npm包 ,并上传到npm中进行下载

1. 模块化 模块化是指将一个大的程序文件&#xff0c;拆分为许多小的文件&#xff08;模块&#xff09;&#xff0c;然后将小的文件组合起来。 1.1. 优点 &#xff08;1&#xff09;防止命名冲突 &#xff08;2&#xff09;代码复用 &#xff08;3&#xff09;高维护性 &…

【CFP-专栏2】计算机类SCI优质期刊汇总(含IEEE/Top)

一、计算机区块链类SCI-IEEE 【期刊概况】IF:4.0-5.0, JCR2区&#xff0c;中科院2区&#xff1b; 【大类学科】计算机科学&#xff1b; 【检索情况】SCI在检&#xff1b; 【录用周期】3-5个月左右录用&#xff1b; 【截稿时间】12.31截稿&#xff1b; 【接收领域】区块链…

利用idea+ jclasslib插件查看和分析 Java 类文件的字节码

jclasslib介绍 jclasslib 插件是一个用于 IntelliJ IDEA 的工具&#xff0c;它允许开发者在集成开发环境&#xff08;IDE&#xff09;内直接查看和分析 Java 类文件的字节码。这个插件尤其对于想要深入了解 Java 字节码、类加载机制、以及 Java 虚拟机&#xff08;JVM&#xf…

网络基础操作练习

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 手把手教你操作华为设备&#xff0c;新手必看。 实验拓扑图 关于命令行视图 1&#xff09;用户视图 <Huawei> 2&#xff09;系统视图 [Hu…

C++初阶(类中的默认成员函数)

呀哈喽&#xff0c;我是结衣 今天给大家带来的是类里面的默认成员函数&#xff0c;一共有六个默认的成员函数哦&#xff0c;包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;运算符重载函数&#xff0c;const成员函数&#xff0c;那么正篇开始。 文章目…

Go语言中的性能考虑和优化

优化您的Go代码以达到最佳性能 性能优化是软件开发的关键方面&#xff0c;无论您使用哪种编程语言。在这篇文章中&#xff0c;我们将探讨Go语言中的性能考虑和优化&#xff0c;Go是一种以其效率而著称的静态类型和编译语言。我们将深入探讨三个关键领域&#xff1a;分析并发代…

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…

开源可观测性平台Signoz(四)【链路监控及数据库中间件监控篇】

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前文链接&#xff1a; ​​开源可观测性平台Signoz系列&#xff08;一&#xff09;【开篇】​​ ​​开源可观测性平台Signoz&…

CSS之元素转换

我想大家在写代码时有一个疑问&#xff0c;块级元素可以转换成其他元素吗&#xff1f; 让我为大家介绍一下元素转换 1.display:block(转换成块元素) display&#xff1a;block可以把我们的行内元素或者行内块元素转换成块元素 接下来让我为大家演示一下&#xff1a; <!DO…

tcpdump出现permission denied

在使用tcpdump -i eth0 src host 192.168.0.184 and ip and port 22 -nn -w ping.pacp命令抓包并把抓到的数据保存到ping.pacp时&#xff0c;出现了权限错误的报错。但实际上我这里用的是root用户执行的命令。 查阅man手册发现: 在tcpdump中&#xff0c;-Z选项用于在启动数据…

CSS 动态提示框

​​ <template> <div class"terminal-loader"><div class"terminal-header"><div class"terminal-title">提示框</div><div class"terminal-controls"><div class"control close"…

【Matlab】BP 神经网络时序预测算法

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88681507 一&#xff0c;概述 BP 神经网络是一种常见的人工神经网络&#xff0c;也是一种有监督学习的神经网络。其全称为“Back Propagation”&#xff0c;即反向传播算法。BP 神经网络主要由输入层、隐藏层…

SpringValidation自定义注解以及分组校验

SpringValidation的参数校验使用可参考&#xff1a;【SpringMVC应用篇】Spring Validation 参数校验-CSDN博客 目录 1. 引入依赖 2. 自定义注解校验 2.1 创建Validation类 2.2 创建注解对象 2.3 使用注解 3. 分组校验 3.1 实体类内部定义接口 3.2 在参数上指定分组 1. …

git回滚操作,常用场景

文章目录 git回滚操作1.git reset --hard 【版本号】2.回滚后的版本v2又想回到之前的版本v32.1 git reflog 3.git checkout -- 文件名4.git reset HEAD 文件名 git回滚操作 假设我们现在有三个版本 现在回滚一个版本 1.git reset --hard 【版本号】 发现只剩下两个版本了 2.…

51单片机的中断相关知识

51单片机的中断相关知识点 一、中断概念和功能 概念 程序执行过程中CPU会遇到一些特殊情况&#xff0c;是正在执行的程序被“中断”&#xff0c;cpu中止原来正在执行的程序&#xff0c;转到处理异常情况或特殊事件的程序去执行&#xff0c;结束后再返回到原被中止的程序处(断…