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

news2024/11/26 1:33:04

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

日期: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个元素后,重新回到1
        queue<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+1
        order(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,要转换为*TreeNode
            vec = 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开始)相等(即少一层),说明结果集需要增加一层来存放当前节点
      • 将当前节点加入结果集对应层(层数在参数已经指定)
      • 递归:分别将左右节点当作根节点重复上述逻辑

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

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

相关文章

PYQT5如何实现radio和tabwidget的互相联动,点击radio切换tabwidget

最近开发界面&#xff0c;需要做一个功能&#xff1a;tabwidget下面有两个界面&#xff0c;对应两个radio&#xff0c;在我点击一个radio的时候&#xff0c;底下的页面也会随之跳转。 分为几个步骤&#xff1a; 1、将两个radio独立&#xff0c;就是点其中一个的时候&#xff0c…

-Xms8g -Xmx8g -Xmn3g 生产事故-记一次特殊的OOM排查

-Xms8g -Xmx8g -Xmn3g 生产事故-记一次特殊的OOM排查 事故背景 C公司开发人员向A公司开发人员反映某开放接口从2023年3月10日14时许开始无法访问和使用。该系统为某基础数据接口服务&#xff0c;基于 HTTP 协议进行通信。按照惯例&#xff0c;首先排查网络是否异常&#xff0…

5-Servlet

5-Servlet 文章目录 5-ServletServlet概述补充概念&#xff1a;静态资源和动态资源Servlet简介 Servlet开发流程开发方式1--XML配置步骤1&#xff1a;新建一个module&#xff0c;并将其改为Web类型步骤2&#xff1a;开发一个Java类&#xff0c;名为&#xff1a;UserServlet步骤…

【Spring】使用注解开发前提条件

前提&#xff1a;导入约束&#xff0c;添加注解支持 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:con…

浮点数存储

//浮点数存储 int main() {int n 9;//00000000 00000000 00000000 00001001//0 00000000 00000000000000000001001//S E(8bit) M(23bit)//E-126//M0.000000000000000000001001// 0.000000000000000000001001 *2^-126float* pFloat (float*)&n;printf("n的值…

阿里云中的云服务器的ubuntu中的vim没有显示行号

没有行号&#xff1a; 在终端输入命令&#xff1a; vim ~/.vimrc set nu

CRM客户管理系统究竟是什么?如何实施?

很多销售人员都不是特别喜欢使用信息化软件&#xff0c;然而从销售经理的角度看&#xff0c;信息化又的确提升了团队的管理效率和业绩。追究这些矛盾的原因&#xff0c;无外乎几点&#xff1a; 认知角度 → 销售员&#xff1a;数据没用又浪费我时间 VS 销售经理&#xff1a;数…

汉化程序的使用方法

首先&#xff1a;双击打开安装程序&#xff0c;输入密码

零代码编程:用ChatGPT批量提取flash动画swf文件中的mp3

文件夹&#xff1a;C:\迅雷下载\有声绘本_flash[淘宝-珍奥下载]\有声绘本 flash&#xff0c;里面有多个flash文件&#xff0c;怎么转换成mp3文件呢? 可以使用swfextract工具从Flash动画中提取音频&#xff0c;下载地址是http://www.swftools.org/download.html&#xff0c;也…

在HTML单页面中,使用Bootstrap框架的多选框如何提交数据

1.引入Bootstrap CSS和JavaScript文件&#xff1a;确保在HTML页面的标签内引入Bootstrap的CSS和JavaScript文件。可以使用CDN链接或者下载本地文件。 <link rel"stylesheet" href"https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css&q…

数据结构-双向链表

1.带头双向循环链表&#xff1a; 前面我们已经知道了链表的结构有8种&#xff0c;我们主要学习下面两种&#xff1a; 前面我们已经学习了无头单向非循环链表&#xff0c;今天我们来学习带头双向循环链表&#xff1a; 带头双向循环链表&#xff1a;结构最复杂&#xff0c;一般用…

UICollectionView左上对齐布局

最近完成的项目需要左上对齐的瀑布流&#xff0c;每个格子的尺寸不同&#xff0c;可以使用UICollectionView定义不同的尺寸&#xff0c;但是CollectionView的格子高度是相同的&#xff0c;我想要的是这样 左上对齐分别是0、1、2&#xff1b;3、4&#xff1b; 当前只能自定义一个…

音乐免费下载mp3格式+音频格式转换+剪辑音频+合并音频教程

1.在qq音乐网页版搜索想要的歌曲 qq音乐网站&#xff1a;https://y.qq.com/ 如果你是vip可以直接下载vip的歌曲&#xff0c;如果不是选择不是vip的歌曲进行第一步的操作 2.点击播放进入页面后F12拿到音频地址 然后双击src里面的音频地址复制 网页新标签打开赋值的这个链接&a…

Harbor私有仓库

Harbor私有仓库 文章目录 Harbor私有仓库Harbor简介&#xff1a;Harbor 提供了以下主要功能和特性&#xff1a;优缺点&#xff1a;环境说明&#xff1a;部署harbor1.永久关闭防火墙和seliux&#xff0c;配置阿里云源&#xff0c;添加映射关系2.安装docker&#xff0c;开启docke…

西瓜书笔记

周志华老师亲讲-西瓜书全网最详尽讲解-1080p高清原版《机器学习初步》 周志华机器学习&#xff08;西瓜书&#xff09;学习笔记&#xff08;持续更新&#xff09; 周志华《Machine Learning》学习笔记 绪论 基本术语 数据集&#xff08;data set&#xff09;&#xff1a;一堆…

常见React Hooks 钩子函数用法

一、useState useState()用于为函数组件引入状态&#xff08;state&#xff09;。纯函数不能有状态&#xff0c;所以把状态放在钩子里面。 import React, { useState } from react import ./Button.cssexport function UseStateWithoutFunc() {const [name, setName] useStat…

RK3588平台开发系列讲解(显示篇)MIPI 屏幕驱动调试

🚀返回专栏总目录 文章目录 一、背光驱动1.1、背光 PWM 节点设置1.2、backlight 节点设置二、屏幕初始化序列发送时序参数设置2.1、设备树下 DSI 节点编写2.2、DSI 的 panel 子节点编写沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 调试 MIPI 屏幕主要有三部分内容…

Qt Creator插件

这里以Qt Creator 4.15.2版本的源码为示例进行分析 源码结构如下&#xff0c;为了追溯其插件加载过程&#xff0c;从main.cpp入手 Qt Creator的插件目录&#xff0c;生成的插件&#xff0c;好几十个呢 Qt Creator插件的读取 int main(int argc, char **argv)中以下代码创建插…

jenkins Java heap space

jenkins Java heap space&#xff0c;是内存不够。 两个解决方案&#xff1a; 一&#xff0c;修改配置文件 windows系统中&#xff0c;找到Jenkins的安装路径&#xff0c; 修改jenkins.xml 将 -Xmx256m 改为 -Xmx1024m 或者更大 重启jenkins服务。 二&#xff0c;jenkins增…