| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 【每日力扣30】二叉树的层序遍历 -> 正文阅读 |
|
[数据结构与算法]【每日力扣30】二叉树的层序遍历 |
一、题目[LeetCode-102]给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1:
示例 2:
示例 3:
提示:
二、思路迭代-队列由题意知,需要对数进行层次(序)遍历,可引入一个队列,维护树节点的访问顺序。开始时插入根节点入队列中。只要队列不为空,便取出一个队列头进行分析,先对其进行需要的操作,再将其子节点入队。本题中的“所需操作”即将节点的值插入一个二维数组中。 本题难点在于如何确定在队列中到底哪些节点属于同一层,从而将相同层的节点的值放入二维数组的同一行中。 这里可以利用队列的size()方法,在开始访问第i层的第一个节点之前,队列的size()便是第i层的节点数目。因此,可以在取出每层的第一个节点之前先套用一个for循环,循环次数即为q.size()。
注意:for循环的写法细节: int?n?=?q.size(); for?(int?i?=?0;?i?<?n;?i++) 这里先声明了n来存储q.size(),然后再在for循环中将i<n作为边界条件。为什么不可以直接 for?(int?i?=?0;?i?<?q.size();?i++) 呢? 因为在for循环中由于父节点的取出和子节点的插入,q.size()是动态变化的。而我们想要的循环次数是进行遍历取出该层第一个节点之前的size(),因此需要先用一个变量n来存储先前的q.size()。否则,如下图所示,可以细细品味。 ? ?三、官方题解(来源:力扣(LeetCode))广度优先搜索我们可以想到最朴素的方法是用一个二元组 (node, level) 来表示状态,它表示某个节点和它所在的层数,每个新进队列的节点的 level 值都是父亲节点的 level 值加一。最后根据每个点的 level 对点进行分类,分类的时候我们可以利用哈希表,维护一个以 level 为键,对应节点值组成的数组为值,广度优先搜索结束以后按键 level 从小到大取出所有值,组成答案返回即可。 考虑如何优化空间开销:如何不用哈希映射,并且只用一个变量 node 表示状态,实现这个功能呢? 我们可以用一种巧妙的方法修改广度优先搜索:
求当前队列的长度si 依次从队列中取si个元素进行拓展,然后进入下一次迭代 它和普通广度优先搜索的区别在于,普通广度优先搜索每次只取一个元素拓展,而这里每次取si个元素。在上述过程中的第 i 次迭代就得到了二叉树的第 i 层的si个元素。 为什么这么做是对的呢?我们观察这个算法,可以归纳出这样的循环不变式:第 i 次迭代前,队列中的所有元素就是第 i 层的所有元素,并且按照从左向右的顺序排列。证明它的三条性质(你也可以把它理解成数学归纳法):
复杂度分析 记树上所有节点的个数为 n。
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 18:25:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |