算法套路九——二叉树广度优先遍历(层序遍历)

news2024/11/13 19:55:09

算法套路九——二叉树广度优先遍历(层序遍历)

算法示例LeetCode102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述

法一:双数组

在层序遍历时采用两个数组来记录,如下图所示,cur记录当前结点,通过遍历cur将cur中的节点的子结点放入nxt中,同时将cur值记录在vlas中,之后令cur=nxt重新遍历cur。
在这里插入图片描述
在这里插入图片描述
cur为空时即所有结点遍历完成,退出循环。

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:
            return []
        cur=[root]
        ans=[]
        while cur:
            nxt=[]
            vals=[]
            for node in cur:
                vals.append(node.val)
                if node.left: nxt.append(node.left)
                if node.right:nxt.append(node.right)
            cur=nxt
            ans.append(vals)
        return ans

法二:队列

与两个数组类似,队列中首先存当前遍历的节点,之后根据当前队列的长度遍历队列,将每个节点的左右子结点加入队列中,并将队列最左侧元素出队。

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root is None:
            return []
        q=deque([root])
        ans=[]
        while q:
            vals=[]
            for _ in range(len(q)):
                node=q.popleft()
                vals.append(node.val)
                if node.left: q.append(node.left)
                if node.right:q.append(node.right)
            ans.append(vals)
        return ans

这两种方法只有细微的地方有代码的区别,故可以选一种自己认为比较顺手的作为常用解法

算法练习一:LeetCode103. 二叉树的锯齿形层序遍历

给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。在这里插入图片描述

本题与上题类似,只是需要增加一个bool变量even记录当前层数是否为偶数,若为偶数,则需要在将值添加进vals进行反向添加,即vals[len(cur)-1-i]=node.Val

法一:双数组

func zigzagLevelOrder(root *TreeNode) (ans [][]int) {
    if root==nil{
        return 
    }
    cur:=[]*TreeNode{root}
    even:=false
    for len(cur)>0{
        nxt:=[]*TreeNode{}
        vals:=make([]int,len(cur))
        for i,node:=range cur{
            if even{vals[len(cur)-1-i]=node.Val}else{vals[i]=node.Val }
            if node.Left != nil {nxt  = append(nxt , node.Left)}
            if node.Right != nil { nxt  = append(nxt , node.Right)}
        }
        cur=nxt
        even = !even
        ans=append(ans,vals)
    }
    return
}

法二:队列

func zigzagLevelOrder(root *TreeNode) (ans [][]int) {
    if root==nil{
        return 
    }
    q:=[]*TreeNode{root}
    even:=false
    for len(q)>0{
        n:=len(q)
        vals:=make([]int,n)
        for i:=0;i<n;i++{//对遍历变量有修改时,不能使用for range遍历
            node:=q[0]
            q=q[1:]
            if even{vals[n-1-i]=node.Val}else{vals[i]=node.Val }
            if node.Left != nil {q = append(q, node.Left)}
            if node.Right != nil { q = append(q, node.Right)}
        }
        ans=append(ans,vals)
        even=!even
    }
    return
}

算法练习二:LeetCode104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。
在这里插入图片描述

本题在之前使用了递归解决,这里使用广度优先层序遍历队列来解决

法一:双数组

func maxDepth(root *TreeNode)  int {
    if root==nil{
        return 0
    }
    cur:=[]*TreeNode{root}
    maxD:=0
    for len(cur)!=0{
        nxt:=[]*TreeNode{}
        maxD++
        for _,node:=range cur{
            if node.Left!=nil{nxt=append(nxt,node.Left)}
            if node.Right!=nil{nxt=append(nxt,node.Right)}
        }
        cur=nxt 
    }
    return maxD
}

法二:队列

func maxDepth(root *TreeNode)  int {
    if root==nil{
        return 0
    }
    q:=[]*TreeNode{root}
    maxD:=0
    for len(q)!=0{
        maxD++
        n:=len(q)
        for i:=0;i<n;i++{
            node:=q[0]
            q=q[1:]
            if node.Left!=nil{q=append(q,node.Left)}
            if node.Right!=nil{q=append(q,node.Right)}
        }
        
    }
    return maxD
}

算法练习三:LeetCode111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。
在这里插入图片描述

使用广度优先搜索的方法遍历整棵树。
当我们找到一个叶子节点时,直接返回这个叶子节点的深度。层序遍历的性质保证了最先搜索到的叶子节点的深度一定最小。

func minDepth(root *TreeNode) int {
    if root==nil{
        return 0
    }
    minD:=0
    q:=[]*TreeNode{root}
    for len(q)!=0{
        minD++
        n:=len(q)
        for i:=0;i<n;i++{
            node:=q[0]
            q=q[1:]
            if node.Left==nil&&node.Right==nil{return minD}
            if node.Left!=nil{q=append(q,node.Left)}
            if node.Right!=nil{q=append(q,node.Right)}
            }
        }
        return -1
}

算法进阶一:LeetCode513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。假设二叉树中至少有一个节点。
在这里插入图片描述

此题有一定难度,因为是要找到最底层最左边节点的值,想到层序遍历,那么如何得到最左边的节点呢,我们可以在进行层序遍历时每次都从右往左入队,这样每次都是上层、右边的节点先出队,故最底层最左边的节点最后出队

func findBottomLeftValue(root *TreeNode) int {
    q:=[]*TreeNode{root}
    var node *TreeNode
    for len(q)>0{
        node=q[0]
        q=q[1:]
        if node.Right!=nil{
            q=append(q,node.Right)
        }
        if node.Left!=nil{
            q=append(q,node.Left)
        }
    }
    return node.Val
}

算法进阶二:LeetCode199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象站在它的右侧,按照从顶部到底部的顺序,返回从右侧能看到的节点值。
在这里插入图片描述

此题之前使用深度遍历递归时有一定难度,但如果使用广度优先的层序遍历,则很明显,只需要记录队列每一层的最后一个结点即可

func rightSideView(root *TreeNode) []int {
    if root==nil{
        return []int{}
    }
    ans:=[]int{}
    q:=[]*TreeNode{root}
    for len(q)!=0{
        n:=len(q)
        for i:=0;i<n;i++{
            node:=q[0]
            q=q[1:]
            if node.Left!=nil{q=append(q,node.Left)}
            if node.Right!=nil{q=append(q,node.Right)}
            if i==n-1{
                ans=append(ans,node.Val)
            }
        }   
    }
    return ans
}

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

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

相关文章

二极管初识

二极管初识 二极管的主要参数如下&#xff1a; 一般的二极管可以在正向或反向偏置条件下工作。 当二极管正向偏置时&#xff0c;需要经过一定的电压降&#xff08;硅为0.7V&#xff0c;锗为0.3V&#xff09;&#xff0c;才能让电流开始流动。此后&#xff0c;二极管上的电压…

【Vue】学习笔记-绑定样式/条件样式

绑定样式/条件样式 绑定样式条件渲染 绑定样式 class样式 写法 :class"xxx" xxx可以是字符串&#xff0c;对象&#xff0c;数组 字符串写法适用于&#xff1a;类名不确定&#xff0c;要动态获取。 对象写法适用于&#xff1a;要绑定多个样式&#xff0c;个数不确定&…

如何给ClickHouse表生成随机真实测试数据

学习ClickHouse数据库&#xff0c;通常需要下载官网一些示例数据。我们也可以通过内置函数generateRandom快速生成测试数据&#xff0c;从而测试学习一些特性的性能及底层原理。 函数语法 generateRandom函数基于给定schema生成随机数据&#xff0c;用于填充测试表。不是所有类…

【SSM】SpringMVC(三:SpringMVC拦截器)

文章目录 1. 登录案例2. 拦截器2.1 应用2.2 拦截器的执行原理2.3 拦截器执行的时机2.4 拦截器的实现方法2.5 拦截器的实现步骤2.6 开发拦截器 1. 登录案例 【login.jsp】 <%--Created by IntelliJ IDEA.User: BeyongDate: 2023/4/17Time: 11:43To change this template use…

【虹科】深度相机对比测评:虹科HK OAK-D Pro VS 英特尔RealSense D435i

虹科致力于为用户提供最优的机器视觉解决方案。本文将用虹科的AI深度相机与英特尔的深度相机来做图像的对比测试&#xff0c;那么它们有哪些性能差异呢&#xff1f; 虹科深度相机 HK OAK-D Pro有两个核心功能&#xff1a;红外激光点阵投影仪和红外照明LED。 红外激光点阵投影…

不能使用chatGPT?这3个平替甚至比chatGPT更强

不能使用chatGPT&#xff1f;这3个平替甚至比chatGPT更强 chatGPT&#xff0c;一款由OpenAI开发的新型AI聊天机器人&#xff0c;正在势如破竹地改变着许多人的工作和生活方式。作为一款基于大语言模型的聊天机器人&#xff0c;chatGPT能够理解自然语言并进行人机对话。与传统的…

SeeThroughNet:通过保留类概率信息来恢复辅助损失

文章目录 SeeThroughNet: Resurrection of Auxiliary Loss by Preserving Class Probability Information摘要本文方法Class Probability Preserving PoolingSeeThroughNet SeeThroughNet: Resurrection of Auxiliary Loss by Preserving Class Probability Information 摘要 …

华为OD机试真题(Java),计算最大乘积(100%通过+复盘思路)

一、题目描述 给定一个元素类型为小写字符串的数组&#xff0c;请计算两个没有相同字符的元素长度乘积的最大值&#xff0c; 如果没有符合条件的两个元素&#xff0c;返回0。 二、输入描述 输入为一个半角逗号分隔的小写字符串的数组&#xff0c;2 < 数组长度<100&am…

李志飞 All in AGI,出门问问大模型来了!

作者 | 唐小引 头图 | 由作者使用出门问问言之画生成 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 大模型进入百模大战唯快不破之时&#xff0c;矢志 Build AGI and make AGI accessible 的李志飞的产品比要组公司拉团队的王小川来得还更快些。 北京时间 4 月…

【C】Array

系列连载 【python / C / C】 参考 《C语言程序设计&#xff08;第四版&#xff09;谭浩强》【C语言】C语言视频教程《郝斌 C 语言自学教程》 文章目录 为什么需要数组数组的分类一维数组二维数组多维数组 #include<stdio.h>int main(){int a[5] { 1, 2, 3, 4, 5 };f…

自学Android开发至少要学到什么程度才可以去面试

前不久&#xff0c;有位网友私信找到我&#xff0c;说自己自学Android已经有两个月左右了&#xff0c;每天至少学习了五个小时&#xff0c;基本都是在网上找视频看跟着做笔记学的&#xff0c;然后就问我&#xff0c;说想这样学&#xff0c;至少需要学到什么程度才可以出去找工作…

Netty Jemalloc4算法-核心数据结构图示

Netty 从4.1.52版本开始&#xff0c;其内存分配算法&#xff0c;从jemalloc3 切换到了 jemalloc4。本文给出该算法涉及的核心数据结构图示&#xff1a; 想要看懂上图, 要点如下&#xff1a; 1. 小于等于16777216字节的空间&#xff0c;从chunk(一个16M的字节数组)中分配&#…

消息队列的选型

目录 消息队列的比较&#xff1a; kafka的架构&#xff1a; kafka为什么可以做到这么高的吞吐量&#xff1a; kafka分区类型&#xff1a; 请看下篇文章:生产者 ACK的配置 消息队列的比较&#xff1a; 消息队列的产品有很多中比如&#xff1a;React MQ 、Kafka等。 为什么…

一文速学数模-季节性时序预测SARIMA模型详解+Python实现

目录 前言 一、季节时间序列模型概述 二、SARIMA模型定义 三.SARIMA模型算法原理 1.季节差分&#xff1a;消除季节单位根 2.ARIMA模型 1.自回归(AR) 2.差分(I) 3.移动平均(MA) 4.ARIMA 四.SARIMA模型Python实现 1.数据预处理 季节性分析 ADF检验 序列平稳化 2.模…

C语言学习分享(第四次)------分支和循环语句

分支和循环语句 1. 前言2. 什么是语句?3. 分支语句(选择结构)3.1 if语句3.11 代码块{}的作用3.12 悬空else3.13 练习 3.2 switch语句3.21 在switch语句中的 break3.22 switch语句中的default子句3.23 练习 4. 循环语句4.1 while循环4.11 while循环中的break4.12 while循环中的…

DNS服务器配置与使用【CentOS】

从本质上说&#xff0c;DNS是一个分布数据库&#xff0c;是一个树形结构&#xff08;不是网状&#xff09;——层次结构 DNS查找过程就是 回溯的过程&#xff08;递归、迭代&#xff09; www.xxx.edu.cn&#xff08;属于四层结构&#xff09; 查询DNS&#xff1a;域名到IP地址的…

Mysql 学习(五)InnDB 存储引擎-B+树索引的使用

基础知识 了解了表索引的底层是B树结构&#xff0c;我们也要学会如何将这个结构的优势发挥出来&#xff0c;我们先来回顾上一节的重点&#xff0c;也就是总结一下B树的特点索引对应的是一棵B树&#xff0c;而B树对应的很多层&#xff0c;每一层存储的数据对应的是下一层节点的…

使用VS2022打包C#项目生成setup文件并部署

首先安装工具 新建Setup项目 先将\bin\Debug下的生成文件添加到里面 添加文件夹将我们需要的文件放入 添加项目输出 在用户桌面添加快捷方式 简单的安装 其实右键项目》生成&#xff0c;然后就在debug这个目录下 下一步下一步就可以了 安装好桌面就有了 添加卸载…

如何把较大的word文档压缩变小,3个高效处理法

在日常工作和学习中&#xff0c;我们经常使用word文档来创建和编辑文件。由于Word文档提供了创建专业和精美文档的便捷工具&#xff0c;并且能够节省用户大量的时间&#xff0c;因此是用户使用频率最高的文字处理程序之一。然而&#xff0c;一些较大的Word文档会占用大量存储空…

【JAVA程序设计】(C00129)基于Springboot+Vue前后端分离的在线考试管理系统

基于SpringbootVue前后端分离的在线考试管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 基于Springbootvue开发的前后端分离的学生考试系统为三个角色&#xff1a;系统管理员、教师、学生 管理员角色包含以下功能&#xff1a; 题库管理、试题管理、考试管理、阅…