力扣日记11.7-【二叉树篇】二叉树的层序遍历

2023-11-07 17:28

本文主要是介绍力扣日记11.7-【二叉树篇】二叉树的层序遍历,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

力扣日记:【二叉树篇】二叉树的层序遍历

日期:2023.11.7
参考:代码随想录、力扣

102. 二叉树的层序遍历

题目描述

难度:中等

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

输入:root = [1]
输出:[[1]]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目在范围 [0, 2000] 内
  • -1000 <= Node.val <= 1000

题解

cpp ver
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
#define SOLUTION 2
#if SOLUTION == 1   // 迭代遍历
class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {// 层序遍历需要将二叉树按层保存在一个二维数组中// 思路:// 1. 首先记录队列长度size,即需要连续弹出的元素个数(某一层元素的个数)// 2. 每弹出一个元素后,将元素的左右节点加入队列// 3. 在连续弹出size个元素后,重新回到1queue<TreeNode*> q;vector<vector<int>> result;if (root != NULL) q.push(root);while (!q.empty()) {int size = q.size();    // 首先记录队列长度,即当前层元素个数vector<int> res;    // 存放当前层元素while (size--) {TreeNode* node = q.front(); // 弹出元素q.pop();res.push_back(node->val);// 将左右节点加入队列if (node->left != NULL)     q.push(node->left);if (node->right != NULL)    q.push(node->right);}// 将当前层元素加入数组result.push_back(res);}return result;}
};
#elif SOLUTION == 2 // 递归遍历
class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;if (root == NULL)   return result;int depth = 0;order(root, result, depth);return result;}void order(TreeNode* cur, vector<vector<int>>& result, int depth) {// 输入参数:当前节点, 结果集指针(需要为指针!), 当前节点所在层数// 终止条件:当前节点为空if (cur == NULL) return;// 处理逻辑:// 如果结果集大小(层数)与所需深度(depth从0开始)相等(即少一层),说明结果集需要增加一层来存放当前节点if (result.size() == depth) result.push_back(vector<int>());// 将当前节点加入结果集对应层(层数在参数已经指定)result[depth].push_back(cur->val);// 递归:将左节点当作根节点重复上述逻辑order(cur->left, result, depth + 1);    // depth + 1,表示第一个参数指定的节点所在层数为depth+1order(cur->right, result, depth + 1);   // 注意cur->right的深度与cur->left一样,不会受上面的递归影响}
};
#endif
go ver
/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func levelOrder(root *TreeNode) [][]int {// go中的队列可通过list实现/*import "container/list"// 创建一个新的双向链表queue := list.New()// 入队操作queue.PushBack(1)// 出队操作if queue.Len() > 0 {front := queue.Front()queue.Remove(front)fmt.Println("出队元素:", front.Value)}*/queue := list.New()res := [][]int{}if root != nil {queue.PushBack(root)}for queue.Len() > 0 {// 记录当前队列长度size := queue.Len()vec := []int{}for size > 0 {// 弹出并写入结果front := queue.Front()node := queue.Remove(front).(*TreeNode) // 存进list之后类型会变为*list.Element,要转换为*TreeNodevec = append(vec, node.Val)// 左右节点入队列if node.Left != nil {queue.PushBack(node.Left)}if node.Right != nil {queue.PushBack(node.Right)}size -= 1}res = append(res, vec)}return res
}

复杂度

时间复杂度:
空间复杂度:

思路总结

  • 层序遍历写法较固定,可作为模板
    • 1.首先记录队列长度size,即需要连续弹出的元素个数(某一层元素的个数)
    • 2.每弹出一个元素后,将元素的左右节点加入队列
    • 3.在连续弹出size个元素后,重新回到1
  • 对于递归写法:
    • 输入参数:当前节点, 结果集指针(需要为指针!), 当前节点所在层数
    • 终止条件:当前节点为空
    • 处理逻辑:
      • 如果结果集大小(层数)与所需深度(depth从0开始)相等(即少一层),说明结果集需要增加一层来存放当前节点
      • 将当前节点加入结果集对应层(层数在参数已经指定)
      • 递归:分别将左右节点当作根节点重复上述逻辑

这篇关于力扣日记11.7-【二叉树篇】二叉树的层序遍历的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

python进行while遍历的常见错误解析

《python进行while遍历的常见错误解析》在Python中选择合适的遍历方式需要综合考虑可读性、性能和具体需求,本文就来和大家讲解一下python中while遍历常见错误以及所有遍历方法的优缺点... 目录一、超出数组范围问题分析错误复现解决方法关键区别二、continue使用问题分析正确写法关键点三

Java遍历HashMap的6种常见方式

《Java遍历HashMap的6种常见方式》这篇文章主要给大家介绍了关于Java遍历HashMap的6种常见方式,方法包括使用keySet()、entrySet()、forEach()、迭代器以及分别... 目录1,使用 keySet() 遍历键,再通过键获取值2,使用 entrySet() 遍历键值对3,

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

两数之和--力扣1

两数之和 题目思路C++代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们在map中能够找到这个差值,就说明存在两个整数的和为目标值。 如果没有找到,就将当前循环的nums[i]以及下标i放入map中,以便后续查

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

力扣第347题 前K个高频元素

前言 记录一下刷题历程 力扣第347题 前K个高频元素 前K个高频元素 原题目: 分析 我们首先使用哈希表来统计数字出现的频率,然后我们使用一个桶排序。我们首先定义一个长度为n+1的数组,对于下图这个示例就是长度为7的数组。为什么需要一个长度为n+1的数组呢?假如说总共有三个数字都为1,那么我们需要把这个1放在数组下标为3的位置,假如说数组长度为n,对于这个例子就是长度为3,那么它的

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结,删除链表节点问题使用到列表,哈希表,递归比较容易超时,我觉得使用计数排序比较稳,处理起来也不是很难。 1. 力扣3217:从链表中移除在数组中的节点 1.1 题目: 给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。 示例 1: 输入: nums = [1,2,3], head = [1,2,3,

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调