【刷题笔记】二叉树2

news2024/11/25 14:29:16

1 二叉树的层序遍历

        上一期我们讲了关于二叉树的前序、中序以及后序遍历的相关内容。然而,还存在一种遍历方式,这种方式非常符合我们人类的正常思维,可以求解很多树相关的问题,比较暴力——二叉树的层序遍历。

        二叉树的层序遍历与前中后序遍历分别对应于图论中的广度优先和深度优先搜索,大家可以好好体会深度和广度这两个词。画个图来增强理解:

        像左图一层一层的遍历就是广度优先,类似于二叉树的层序遍历,像右边这种,一个方向一个方向的遍历就是深度优先,类似于我们的前中后序遍历。 

2 解法套路

        二叉树的层序遍历,有非常明显的套路。102. 二叉树的层序遍历,以这道题为例,先贴代码:

    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Deque<TreeNode> deque = new LinkedList();
        deque.push(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            List<Integer> path = new ArrayList<>();
            while (size-- > 0) {
                TreeNode p = deque.pollFirst();
                path.add(p.val);
                if (p.left != null) {
                    deque.addLast(p.left);
                }
                if (p.right != null) {
                    deque.addLast(p.right);
                }
            }
            res.add(path);
        }
        return res;
    }

        (1)定义一个队列,先把树的头节点放入队列头。

        (2)定义一个循环,如果队列不为空,就一直循环下去。

        (3)求队列的长度,这个长度代表了树当前层的节点数。

        (4)然后,开始从队列中弹出所有元素,每弹出一个元素,就把他的左节点和右节点加入到队列的尾部,当这一层所有节点都被弹完后,是不是下一层就重新填充了队列。

        (5)直到最后一层。

3 相关例题

3.1 二叉树的层序遍历Ⅱ

107. 二叉树的层序遍历 II

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

    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            List<Integer> list = new ArrayList<>();
            while (size-- > 0) {
                TreeNode node = deque.pollFirst();
                list.add(node.val);
                if (node.left != null) {
                    deque.addLast(node.left);
                }
                if (node.right != null) {
                    deque.addLast(node.right);
                }
            }
            res.add(0, list);
        }
        return res;
    }

        这道题和上面的例题,几乎完全相同,只不过是从下往上输出。那我们可以利用List列表的特性,每次都在0的位置add,最后展示的时候就是从下往上。

3.2 二叉树的层平均值

637. 二叉树的层平均值

        给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10^{-5} 以内的答案可以被接受。(这句话告诉我们定义sum的时候要用double)

    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> res = new ArrayList<>();
        Deque<TreeNode> deque = new LinkedList();
        deque.push(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            Double sum = 0d;
            int nums = size;
            while (size-- > 0) {
                TreeNode pop = deque.pop();
                sum += pop.val;
                if (pop.left != null) {
                    deque.addLast(pop.left);
                }
                if (pop.right != null) {
                    deque.addLast(pop.right);
                }
            }
            res.add(sum / nums);
        }
        return res;
    }

        这道题用层序做非常简单,但是也可以用前序遍历去做,大家可以思考一下,怎么用前序做,下一期我会给出详解。

3.3 N叉树的层序遍历

429. N 叉树的层序遍历

        给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。树的序列化输入是用层序遍历,每组子节点都由 null 值分隔。

    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Deque<Node> deque = new LinkedList<>();
        deque.push(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            List<Integer> list = new ArrayList<>();
            while (size-- > 0) {
                Node pop = deque.pop();
                list.add(pop.val);
                if (pop.children != null) {
                    for (Node child : pop.children) {
                        deque.addLast(child);
                    }
                }
            }
            res.add(list);
        }
        return res;
    }

        万变不离其宗,二叉树都是左节点、右节点,N叉树是一个节点下面挂了一个列表,列表中装着它的孩子节点,与二叉树对应,那就每次队列弹出这个节点的时候就把它的孩子节点列表遍历了,都从队列尾部装进去就好了。

3.4 二叉树层最大值

        给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

    public List<Integer> largestValues(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Deque<TreeNode> deque = new LinkedList<>();
        deque.push(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            int maxValue = deque.peek().val;
            while (size-- > 0) {
                TreeNode pop = deque.pop();
                maxValue = Math.max(maxValue, pop.val);
                if (pop.left != null) {
                    deque.addLast(pop.left);
                }
                if (pop.right != null) {
                    deque.addLast(pop.right);
                }
            }
            res.add(maxValue);
        }
        return res;
    }

        这道题同样可以用前序遍历去做,但是层序比较容易想,且时间复杂度和前序都是O(N),所以还是建议大家用层序去做。下一期会出前序解法。、

4 总结

        二叉树的层序遍历套路非常明显,可以解决很多树的问题,不过用层序解答的结果就是时间复杂度都是O(N),所以层序遍历适合那些无论如何都要遍历整棵树的题,例如,求层平均值、求层最大值、求二叉树最大深度、求二叉树最小深度,这些题是你要把整棵树遍历完才能知道答案的,但是用前中后序(深度优先)遍历也可以解决,且时间复杂度也是O(N),只不过相比之下可能层序更容易想。

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

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

相关文章

股票买卖的思路与代码

题目 1302&#xff1a;股票买卖 时间限制: 1000 ms 内存限制: 65536 KB 提交数:8660 通过数: 4290 【题目描述】 最近越来越多的人都投身股市&#xff0c;阿福也有点心动了。谨记着“股市有风险&#xff0c;入市需谨慎”&#xff0c;阿福决定先来研究一下简化版的股…

文华软件自动画线 参数自调 多空波段变色线(源码自取)

编写思路 想要随意输入一个点位&#xff0c;即可按照这个点位自动画线&#xff0c;此线可以多空变色&#xff0c;上下突破线时箭头提示并发出声音预警。 代码函数重点解析 A、DRAWSL 绘制直线&#xff08;段&#xff09;。 用法&#xff1a; DRAWSL(COND,DATA,SLOPE,LEN,E…

【OpenCV】111

1 新建项目 新建项目&#xff0c;路径不要出现中文 文件夹名称 添加解释器&#xff0c;添加本地解释器 这样就创建好了一个文件夹&#xff0c;然后像我这样一级一级向下分&#xff0c;细分文件夹

TinyC编译器5—词法分析

1.词法分析的基本概念 词法分析也称为分词&#xff0c;此阶段编译器从左向右扫描源文件&#xff0c;将其字符流扫描分割成一个个的词&#xff08;记号、token&#xff09;。所谓token&#xff0c;就是源文件中不可再进一步分割的一串字符&#xff0c;类似英语中的单词&#xf…

Transformer大模型在训练过程中所需的计算量

目录 简介计算需求参数与数据集的权衡计算成本的工程意义内存需求推理模型权重总推理内存训练模型参数优化器状态梯度激活值和批大小总训练内存分布式训练分片优化器3D 并行分片优化器 + 3D 并行参考简介 许多关于Transformer语言模型的基本且重要的信息都可以用相当简单的方式…

基于微信小程序的大用户心理咨询系统设计与实现---附源码99040

目录 1 绪论 1.1 研究背景 1.2研究现状 1.3论文结构与章节安排 2 基于微信小程序的大用户心理咨询系统设计与实现分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 基于微信小程序的大用户心理咨询系统设计与实现总体设计 3.…

网站首页配置-记录部分错误

目录 错误问题1: 解决方案: 错误问题2: 解决方案&#xff1a; 错误问题3&#xff1a; 解决方案&#xff1a; 错误问题4&#xff1a; 解决方案&#xff1a; EL的作用: 错误问题1: 解决方案: 里面的代码写错&#xff0c;cateSecond应该写成categorySecond 错误问题2: 解…

toRef 与 toRefs

在 ref函数与reactive函数的对比 这一篇博文中&#xff0c;我们从使用角度对比了 ref 与 reactive 的区别&#xff0c;最终得出结论是&#xff0c; 通过 ref 定义的数据&#xff0c;在 js脚本中使用需要 xxx.value &#xff0c;在模板中会自动解包&#xff0c;可以直接使用通过…

WIN 10 添加右键菜单(VSCode 打开当前目录)

WIN 10 添加右键菜单&#xff08;VSCode 打开当前目录&#xff09; 前言最终效果操作步骤 前言 每次打开代码都需要先打开 VSCode&#xff0c;再选择最近打开的项目或者浏览打开项目&#xff0c;感觉比较难找。所以自己添加了右键命令。 最终效果 操作步骤 cmd 打开注册表 找…

20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并启动

20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并启动 2024/8/21 15:22 viewproviewpro-ThinkBook-16-G5-IRH:~/repo_RK3588_Buildroot20240508$ viewproviewpro-ThinkBook-16-G5-IRH:~/repo_RK3588_Buildroot20240508$ ./build.sh lunch 3. rockchip_rk3588_evb7_…

C++智能指针的用法(全)

一、智能指针概念 C/C 语言最为人所诟病的特性之一就是存在内存泄露问题&#xff0c;因此后来的大多数语言都提供了内置内存分配与释放功能&#xff0c;有的甚至干脆对语言的使用者屏蔽了内存指针这一概念。这里不置贬褒&#xff0c;手动分配内存与手动释放内存有利也有弊&…

普元EOS-基于CriteriaEntity进行数据查询

1 前言 普元EOS内置了一系列数据库的操作类&#xff0c;本文介绍其中的一个类 CriteriaEntity的使用方法。 CriteriaEntity是进行组织数据库查询条件的类&#xff0c;基于该类配合DataObject&#xff0c;实现对数据库的查询。 2 CriteriaType类的实例化 要利用Criteria进行查…

LlamaIndex 实现 RAG (一)

理解过 LlamaIndex 的功能之后&#xff0c;本文通过 LlamaIndex 快速实现一个简单的 RAG 应用&#xff0c;主要包括以下几个部分&#xff1a; 创建知识库&#xff0c;并进行 Embedding集成本地 Ollama 模型或者 Qwen 模型通过 Streamlit 可视化 RAG 文末提供了源代码地址 创…

HarmonyOS开发实战:应用权限/通知设置跳转方案

场景描述 引导用户跳转到系统设置页进行权限&#xff0c;通知的相关设置&#xff0c;类似android和iOS应用中常见的应用内跳转到设置进行通知开启或权限设置的操作。 应用经常会遇到如下的业务诉求&#xff1a; 场景一&#xff1a;如果应用首次拒绝了消息通知&#xff0c;应…

免费高效:2024年四大视频剪辑软件推荐!

不管是不是专业人士&#xff0c;相信大家多多少少都会有视频剪辑的需求&#xff0c;对于很多新手来说&#xff0c;一款好用且免费的视频剪辑工具十分必要&#xff0c;接下来就为大家推荐几个好用的视频剪辑免费软件&#xff01; 福昕视频剪辑 链接&#xff1a;www.pdf365.cn/…

Linux(CentOS7)虚拟机安装教程

创建虚拟机 自定义高级&#xff0c;就下一步 选择Workstation 17.x,完好后就继续下一步,下面就如图所示 虚拟机内存看情况加 磁盘大小也看情况加 完成&#xff01; 开启此虚拟机 鼠标放进去直接回车 可能有点慢&#xff0c;请耐心等待 一.进入日期时间 二.进入软件选择 三.配置…

[创业之路-138] :产品需求、产品研发、产品生产、库存管理、品控、售后全流程 - 时序图

目录 一、产品研发全流程 1. 客户/市场需求 2. 供应链采购 3. 设计研发 4. 库房管理 5. 品控质检 6. 物流运输 7. 客户现场验证 8. 返修售后 二、产品生产全流程 1. 客户/市场需求 2. 供应链采购 3. 生产加工 4. 库房管理 5. 品控质检 6. 物流运输 7. 客户现场…

物理可微分神经算法:深度学习与物理世界的桥梁

物理可微分神经算法&#xff1a;深度学习与物理世界的桥梁 前言物理可微分神经算法的核心PyTorch中的实现讨论与展望结语 前言 在这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动技术革新的关键力量。深度学习&#xff0c;作为AI领域的一个重要分…

CAPL如何实现在网络节点中添加路由Entry

其实不只是CANoe的网络节点,所有设备的应用程序如果要通过Socket套接字发送报文,在网络层都需要根据路由表里配置的路由条目选择发送路径。这个路由条目可以是静态配置,也可以是自动添加。 如果CANoe的网络节点添加一个网络接口,配置IP地址和子网掩码: 说明此网络节点在1…

外挂程序:增强点及辅助

1.关于前几篇介绍的外挂程序,SAP中的业务单据还是要区分具体的操作人员。如建立财务凭证,工号A,B,C使用相同的SAP账号,那就没办法知道是谁操作的了啊,所以sap的业务单据需要细分到具体人员的都要增强实现以下: 如生产工单: 具体的增强点: 2.辅助程序:SAP账号自动锁定功…