当前位置: 首页 > news >正文

【Leetcode】十六、深度优先搜索 宽度优先搜索 :二叉树的层序遍历

文章目录

  • 1、深度优先搜索算法
  • 2、宽度优先搜索算法
  • 3、leetcode102:二叉树的层序遍历
  • 4、leetcode107:二叉树的层序遍历II
  • 5、leetcode938:二叉搜索树的范围和

1、深度优先搜索算法

深度优先搜索,即DFS,从root节点开始,尽可能深的搜索每一个分支。把一个分支的结果搜索完以后,再去看下一个分支。

在这里插入图片描述
应用场景:

  • 二叉树搜索
  • 图搜索

例子:走迷宫,从起点开始,一直走到终点或者撞墙后(这就是所谓的 “深度” 优先),回到起点重新开始,可以找到如下两条路(红色箭头和黄色箭头)

在这里插入图片描述

用深度优先来看前面回溯中提到的子集求法:从起点开始,首先是一个空集。往下有1、2、3三条路可以走
在这里插入图片描述

先逮着1开始走,1符号要求,放入结果集,接着往下走,[1,2],也符合要求,放入结果集,接着往下走,[1,2,3],也符合要求,放入结果集,再往下,就到底了。换另一条路走。

2、宽度优先搜索算法

宽度(广度)优先搜索,即BFS,和DFS不同,BFS是一层一层的处理。BFS一般搭配队列使用。

在这里插入图片描述

BFS和DFS的对比:

在这里插入图片描述

以从上到下、从左到右遍历以下二叉树为例,采用宽度优先,搭配一个队列,先进先出,计数count = 0。从root开始,root入队,count = 1,出队,同时root的左、右节点入队,并维护count。当count = 0时,说明遍历结束。

在这里插入图片描述

即node.val出队,node.left和node.right入队。详细:

  • root节点1入队,count = 1
  • 根据count,从队列中pop元素,得到root节点,把其值val放入结果集,并把其左右孩子加进来。结果集array = [1]
  • 此时,队列中存着2、3这两个节点,count = 2
  • 继续根据count = 2来pop两次,并加入元素的左右孩子
  • pop出元素2,加入其左右节点4、5,count = 3,结果集array = [1,2]
  • pop出元素3,加入其左右节点6、7,count = 4,结果集array = [1,2,3]
  • pop出元素4,count = 3,array = [1,2,3,4]
  • pop出元素7,count = 0,array = [1,2,3,4,5,6,7]

3、leetcode102:二叉树的层序遍历

和上面分析的BFS遍历二叉树不一样,这题要求输出的结果是分层的,考虑一层一层的处理,并把每层的处理完的结果加入最终的结果集。

在这里插入图片描述

外层while执行一次,代表处理了二叉树的一层。内层while执行一次,代表处理这层的每个元素(自身出队、左右节点的值入队)

public class P102 {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> result = new ArrayList<>();if (null == root) {return result;}Queue<TreeNode> queue = new LinkedList<>();queue.add(root);while (queue.size() > 0) {// 存每层的结果List<Integer> list = new ArrayList<>();// 每处理完一层,队列的长度,即是下一层元素的数量int count = queue.size();// 处理每一层的元素,弹出这一层的每个元素,并把每个元素的左右节点加进去while (count > 0) {TreeNode node = queue.poll();list.add(node.val);count--;// 弹出的元素的左右孩子节点的值入队if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}// 一层处理结束,把结果加到结果集里,注意别直接add上面的list,防止引用传递,用copy值传递result.add(new ArrayList<>(list));}return result;}
}

这题很明显的有”层“的概念,用BFS很合适,但DFS也能解。
在这里插入图片描述

从root开始,一条路往下走,和前面一层层的取不一样了,DFS解时,每层递归有个level,level = 0,即root节点所在的那层,放到结果集result的0号位置,往下9,放到result的1号元素里面

public class P102 {public List<List<Integer>> levelOrderByDfs(TreeNode root) {List<List<Integer>> result = new ArrayList<>();if (null == root) {return result;}dfs(root, result, 0);return result;}/*** 深度优先** @param node   节点* @param result 最终的结果集* @param level  二叉树中当前的层级*/public static void dfs(TreeNode node, List<List<Integer>> result, int level) {// 终止条件if (node == null) {return;}// 如果当前层级到了2,那结果集里应该初始化出两个元素,每层的结果存一个结果集的元素里if (level > result.size() - 1) {result.add(new ArrayList<>());}// 层级所在结果集的位置上,加入这个元素result.get(level).add(node.val);if (node.left != null) {dfs(node.left, result, level + 1);}if (node.right != null) {dfs(node.right, result, level + 1);}}
}

4、leetcode107:二叉树的层序遍历II

在这里插入图片描述

和前面102题不同的是,要求从叶子节点开始一层层的遍历,输出的顺序刚好相反,当然,可以在102的代码的末尾,直接reverse翻转答案,然后return。

说起翻转,也可自己用栈实现,但除了翻转,有更优实现:结果集result用一个链表,依旧从root节点那一层开始,从上往下一层层处理,但每层的结果,加到result的头部,如此,从上到下遍历完每层后,直接不用翻转就是题解。

Java中,List里面底层是链表的,就不能用ArrayList(数组),而是LinkedList:

public class P107 {public List<List<Integer>> levelOrderBottom(TreeNode root) {// 用链表对应的LinkedListList<List<Integer>> result = new LinkedList<>();if (null == root) {return result;}// 队列Queue<TreeNode> queue = new LinkedList<>();queue.add(root);while (queue.size() > 0) {int count = queue.size();List<Integer> levelList = new ArrayList<>();for (int i = 0; i < count; i++) {TreeNode node = queue.poll();levelList.add(node.val);if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}// 注意这里,每次add的下标是0,即链表队首,这样第二层的结果就会排到第一层result.add(0, levelList);}return result;}
}

以上实现,注意链表的巧妙之处:

在这里插入图片描述

这题要不用BFS,而DFS,那最后就得reverse翻转一下结果集了。虽然BFS能解的,DFS也能解,但这种层级的遍历,BFS更好用。

最后,以上用到的TreeNode:

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;}
}

5、leetcode938:二叉搜索树的范围和

第一反应是,遍历二叉树,判断每个元素在范围就累加。那应该想到BFS,除了BFS,还有别的实现:不管是前序、中序、后序遍历,一个树,最后肯定会被拆解成一个个只有三个节点的小块,即递归。
在这里插入图片描述

解法一:普通递归

在这里插入图片描述
从root开始,一分为二的看,最终结果 = 左 + 中 + 右,左边有子树的话,继续左 + 中 + 右,纯递归,递归终止的条件为,节点没有子节点了。代码实现:

public class P938 {public int rangeSumBST(TreeNode root, int low, int high) {if (null == root) {return 0;}// 左边那一块,新的root就是root.leftint leftSum = rangeSumBST(root.left, low, high);// 右边那一块,新的root就是root.rightint rightSum = rangeSumBST(root.right, low, high);int result = leftSum + rightSum;// 中间节点if (low <= root.val && root.val <= high) {result = result + root.val;}return result;}
}

以上面二叉树为例:

- 第一次递归:root=10, left=5,right=15
- 第二次递归:root=上一层的root.left=5,left=3,right=7
- 第三次递归:root=上一层的root.left=3,left=null,right=null
- 第四次递归:root=上一层的root.left=null,终止递归,回退,返回0

解法二:BFS

一层层的来,平铺扫荡,每一个出队的元素,判断是否在范围内,是则累加

在这里插入图片描述

这题的BFS,和BFS概念分析时一样,都不用像前两道题一样分层,一层while就行:

public class P938 {public int rangeSumBSTByBFS(TreeNode root, int low, int high) {if (null == root) {return 0;}int result = 0;Queue<TreeNode> queue = new LinkedList<>();queue.add(root);while (!queue.isEmpty()) {TreeNode node = queue.poll();if (node.val >= low && node.val <= high) {result = result + node.val;}// 左右节点处理if (node.left != null) {queue.add(node.left);}if (node.right != null) {queue.add(node.right);}}return result;}
}

相关文章:

【Leetcode】十六、深度优先搜索 宽度优先搜索 :二叉树的层序遍历

文章目录 1、深度优先搜索算法2、宽度优先搜索算法3、leetcode102&#xff1a;二叉树的层序遍历4、leetcode107&#xff1a;二叉树的层序遍历II5、leetcode938&#xff1a;二叉搜索树的范围和 1、深度优先搜索算法 深度优先搜索&#xff0c;即DFS&#xff0c;从root节点开始&a…...

Ruby教程

Ruby是一种动态的、面向对象的、解释型的脚本语言&#xff0c;以其简洁和易读性而闻名。Ruby的设计哲学强调程序员的生产力和代码的可读性&#xff0c;同时也融合了功能性和面向对象编程的特性。 以下是一个基础的Ruby教程&#xff0c;涵盖了一些基本概念和语法&#xff1a; …...

react + pro-components + ts完成单文件上传和批量上传

上传部分使用的是antd中的Upload组件,具体如下: GradingFilingReportUpload方法是后端已经做好文件流,前端只需要调用接口即可 单文件上传 <Uploadkey{upload_${record.id}}showUploadList{false}accept".xlsx"maxCount{1}customRequest{({ file }) > {const …...

暑假第一周——ZARA仿写

iOS学习 前言首页&#xff1a;无限轮播图商城&#xff1a;分类我的&#xff1a;自定义cell总结 前言 结束了UI的基础学习&#xff0c;现在综合运用开始写第一个demo&#xff0c;在实践中提升。 首页&#xff1a;无限轮播图 先给出效果&#xff1a; 无限轮播图&#xff0c;顾…...

github.com/antchfx/jsonquery基本使用

要在 GitHub 上使用 antchfx/jsonquery 库来查找 JSON 文档中的元素&#xff0c;首先需要了解这个库的基本用法。jsonquery 是一个用于查询 JSON 数据的 Go 语言库&#xff0c;允许使用 XPath 表达式来查找和选择 JSON 数据中的元素。 以下是一些基本步骤和示例&#xff0c;演…...

【python虚拟环境管理】【mac m3】使用poetry管理python项目

文章目录 一. 为什么选择poetry二. poetry相关操作1. 创建并激活环境2. 依赖包管理2.1. 安装项目依赖1.2. 管理不同开发环境的依赖1.3. 依赖维护1.4. 项目相关 Poetry是Python中用于依赖管理和打包的工具。它允许您声明项目所依赖的库&#xff0c;并将为您管理&#xff08;安装…...

《JavaSE》---16.<抽象类接口Object类>

目录 前言 一、抽象类 1.1什么是抽象类 1.2抽象类代码实现 1.3 抽象类特点 1.4抽象类的作用 二、接口 2.1什么是接口 2.2接口的代码书写 2.3 接口使用 2.4 接口特点 2.5 实现多个接口 快捷键&#xff08;ctrl i &#xff09;&#xff1a; 2.6接口的好处 2.7 接…...

简单修改,让UE4/5着色器编译速度变快

简单修改&#xff0c;让UE4/5着色器编译速度变快 目录 简单修改&#xff0c;让UE4/5着色器编译速度变快 一、问题描述 二、解决方法 &#xff08;一&#xff09;硬件升级 &#xff08;二&#xff09;调整相关设置和提升优先级 1.调整相关设置 &#xff08;1&#xff09…...

如何查看极狐GitLab Helm Chart?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…...

代码随想录算法训练营第十六天| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

写代码的第十六天&#xff0c;自从到了二叉树错误版代码就少了&#xff0c;因为我自己根本没思路&#xff0c;都是看完思路在做&#xff0c;那基本上就是小语法问题&#xff0c;很少有其他问题了&#xff0c;证实了我好菜。。。。。。 还是得写思路啊啊啊啊&#xff0c;写思路好…...

NODEJS复习(ctfshow334-344)

NODEJS复习 web334 下载源码代码审计 发现账号密码 代码逻辑 var findUser function(name, password){ return users.find(function(item){ return name!CTFSHOW && item.username name.toUpperCase() && item.password password; }); }; 名字不等于ctf…...

【Go系列】RPC和grpc

承上启下 介绍完了Go怎么实现RESTFul api&#xff0c;不可避免的&#xff0c;今天必须得整一下rpc这个概念。rpc是什么呢&#xff0c;很多人都想把rpc和http一起对比&#xff0c;但是他们不是一个概念。RPC是一种思想&#xff0c;可以基于tcp&#xff0c;可以基于udp也可以基于…...

【VUE】v-if和v-for的优先级

v-if和v-for v-if 用来显示和隐藏元素 flag为true时&#xff0c;dom元素会被删除达到隐藏效果 <div class"boxIf" v-if"flag"></div>v-for用来进行遍历&#xff0c;可以遍历数字对象数组&#xff0c;会将整个元素遍历指定次数 <!-- 遍…...

【单目3D检测】smoke(1):模型方案详解

纵目发表的这篇单目3D目标检测论文不同于以往用2D预选框建立3D信息&#xff0c;而是采取直接回归3D信息&#xff0c;这种思路简单又高效&#xff0c;并不需要复杂的前后处理&#xff0c;而且是一种one stage方法&#xff0c;对于实际业务部署也很友好。 题目&#xff1a;SMOKE&…...

数据库系统概论:数据库系统的锁机制

引言 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;数据作为一种共享资源&#xff0c;其并发访问的一致性和有效性是数据库必须解决的问题。锁机制通过对数据库中的数据对象&#xff08;如表、行等&#xff09;进行加锁&#xff0c;以确保在同…...

Django+vue自动化测试平台(28)-- ADB获取设备信息

概述 adb的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用。通过adb可以在Eclipse中通过DDMS来调试Android程序&#xff0c;说白了就是调试工具。 adb的工作方式比较特殊&#xff0c;采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯&#xff0c;默认情况下…...

RESTful API设计指南:构建高效、可扩展和易用的API

文章目录 引言一、RESTful API概述1.1 什么是RESTful API1.2 RESTful API的重要性 二、RESTful API的基本原则2.1 资源导向设计2.2 HTTP方法的正确使用 三、URL设计3.1 使用名词而非动词3.2 使用复数形式表示资源集合 四、请求和响应设计4.1 HTTP状态码4.2 响应格式4.2.1 响应实…...

npm下载的依赖包版本号怎么看

npm下载的依赖包版本号怎么看 版本号一般分三个部分&#xff0c;主版本号、次版本号、补丁版本号。 主版本号&#xff1a;一般依赖包发生重大更新时&#xff0c;主版本号才回发生变化&#xff0c;如Vue2.x到Vue3.x。次版本号&#xff1a;当依赖包中发生了一些小变化&#xff…...

css前端面试题

1.什么是css盒子模型&#xff1f; 盒子模型包含了元素内容&#xff08;content&#xff09;、内边距&#xff08;padding&#xff09;、边框&#xff08;border&#xff09;、外边距&#xff08;margin&#xff09;几个要素。 标准盒子模型和IE盒子模型的区别在于其对元素的w…...

Vue从零到实战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...

【Chatgpt大语言模型医学领域中如何应用】

随着人工智能技术 AI 的不断发展和应用&#xff0c;ChatGPT 作为一种强大的自然语言处理技术&#xff0c;无论是 自然语言处理、对话系统、机器翻译、内容生成、图像生成&#xff0c;还是语音识别、计算机视觉等方面&#xff0c;ChatGPT 都有着广泛的应用前景。特别在临床医学领…...

ES6 正则的扩展(十九)

1. 正则表达式字面量改进 特性&#xff1a;在 ES6 中&#xff0c;正则表达式字面量允许在字符串中使用斜杠&#xff08;/&#xff09;作为分隔符。 用法&#xff1a;简化正则表达式的书写。 const regex1 /foo/; const regex2 /foo/g; // 全局搜索2. u 修饰符&#xff08;U…...

<数据集>钢铁缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1800张 标注数量(xml文件个数)&#xff1a;1800 标注数量(txt文件个数)&#xff1a;1800 标注类别数&#xff1a;6 标注类别名称&#xff1a;[crazing, patches, inclusion, pitted_surface, rolled-in_scale, scr…...

Kafka系列之:Kafka存储数据相关重要参数理解

Kafka系列之:Kafka存储数据相关重要参数理解 一、log.segment.bytes二、log.retention.bytes三、日志段四、log.retention.check.interval.ms五、数据底层文件六、index、log、snapshot、timeindex、leader-epoch-checkpoint、partition.metadata一、log.segment.bytes 参数lo…...

Template execution failed: ReferenceError: name is not defined

问题 我们使用了html-webpack-plugin&#xff08;webpack&#xff09;进行编译html&#xff0c;导致的错误。 排查结果 连接地址 html-webpack-plugin版本低(2.30.1)&#xff0c;html模板里面不能有符号&#xff0c;注释都不行 // var reg new RegExp((^|&)${name}([^&…...

CVE-2024-24549 Apache Tomcat - Denial of Service

https://lists.apache.org/thread/4c50rmomhbbsdgfjsgwlb51xdwfjdcvg Apache Tomcat输入验证错误漏洞&#xff0c;HTTP/2请求的输入验证不正确&#xff0c;会导致拒绝服务&#xff0c;可以借助该漏洞攻击服务器。 https://mvnrepository.com/artifact/org.apache.tomcat.embed/…...

Linux下如何安装配置Graylog日志管理工具

Graylog是一个开源的日志管理工具&#xff0c;可以帮助我们收集、存储和分析大量的日志数据。它提供了强大的搜索、过滤和可视化功能&#xff0c;可以帮助我们轻松地监控系统和应用程序的运行情况。 在Linux系统下安装和配置Graylog主要包括以下几个步骤&#xff1a; 准备安装…...

「MQTT over QUIC」与「MQTT over TCP」与 「TCP 」通信测试报告

一、结论 在实车5G测试中「MQTT Over QUIC」整体表现优于「TCP」&#xff0c;可在系统架构升级时采用MQTT Over QUIC替换原有的TCP通讯&#xff1b;从实现原理上基于QUIC比基于TCP在弱网、网络抖动导致频繁重连场景延迟更低。 二、测试方案 网络类型&#xff1a;实车5G、实车…...

获取磁盘剩余容量-----c++

获取磁盘剩余容量 #include <filesystem>struct DiskSpaceInfo {double total;double free;double available; };DiskSpaceInfo getDiskSpace(const std::string& path) {std::filesystem::space_info si std::filesystem::space(path);DiskSpaceInfo info;info.…...

AI算法24-决策树C4.5算法

目录 决策树C4.5算法概述 决策树C4.5算法简介 决策树C4.5算法发展历史 决策树C4.5算法原理 信息熵&#xff08;Information Entropy&#xff09; 信息增益&#xff08;Information Gain&#xff09; 信息增益比&#xff08;Gain Ratio&#xff09; 决策树C4.5算法改进 …...

越南的网站建设/百度推广优化怎么做的

首先请大家看这么一个简单的小程序&#xff1a; #include <stdio.h>void main(){int i, b[10];for ( i 0; i < 10; i ) { b[i] 0; }} 请问这个程序是否有错&#xff1f;A.正常 B.越界 C.死循环 正确答案是C&#xff0c;相信选A或选B的朋友一定会很纳闷…...

如何用魔方网表做门户网站/写软文一篇多少钱合适

前言 大家好呀&#xff0c;最近很多小伙伴&#xff0c;让我帮忙找找 Java 面试资料。 于是我把以前的面试专栏的文章&#xff0c;整理成PDF啦&#xff01;有MySQL、Redis、消息队列、计算机网络、Zookeeper、Java基础、以及各个大厂的面试真题&#xff0c;大家一起学习&#…...

用模板建商城购物网站/网络营销的4p策略

全国计算机技术与软件专业技术资格(水平)考试 2014年上半年 系统集成项目管理工程师 上午试卷 (考试时间 9 : 00~11 : 30 共 150 分钟) 1. 在答题卡的指定位置上正确写入你的姓名和准考证号,并用正规 2B 铅笔在你写入的准考证号下填涂准考证号。 2. 本试卷的试题中共有…...

怎么样做网站/seo优化工具

最近因为工作需求原因一直使用VUE框架&#xff0c;作为时下最热门的渐进式框架&#xff0c;开发起来确实非常给力~ 当然一个好的工具也不可能完全对你百依百顺&#xff0c;最近在工作中就遇到了一个问题&#xff0c;经过一下午的奋战终于搞定了&#xff0c;秉承着本熊一贯的无私…...

时时彩网站开发代理代码/最新注册域名查询

android:divider"drawable/shape"<!--分割线图片-->android:showDividers"middle|beginning|end" <!--分割线位置-->分割线如果是图片那就直接使用图片就行&#xff0c;如果要使用颜色就必须使用shape来显示&#xff0c;直接使用颜色或Color是…...

合肥网站关键词优化/seo在线外链

大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01;今天来讲讲 Python 语言中一个非常重要的语法概念&#xff1a;函数数学上的函数&#xff0c;是指给定一个输入&#xff0c;就会有唯一输出的一种对应关系。编程语言里的函数跟这个意思差不多&#xff0c;但也有不同。…...