C++力扣题目-- 二叉树层序遍历

  • 102.二叉树的层序遍历(opens new window)
  • 107.二叉树的层次遍历II(opens new window)
  • 199.二叉树的右视图(opens new window)
  • 637.二叉树的层平均值(opens new window)
  • 429.N叉树的层序遍历(opens new window)
  • 515.在每个树行中找最大值(opens new window)
  • 116.填充每个节点的下一个右侧节点指针(opens new window)
  • 117.填充每个节点的下一个右侧节点指针II(opens new window)
  • 104.二叉树的最大深度(opens new window)
  • 111.二叉树的最小深度

102思路:

我们之前讲过了三篇关于二叉树的深度优先遍历的文章:

  • 二叉树:前中后序递归法(opens new window)
  • 二叉树:前中后序迭代法(opens new window)
  • 二叉树:前中后序迭代方式统一写法(opens new window)

接下来我们再来介绍二叉树的另一种遍历方式:层序遍历。

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

使用队列实现二叉树广度优先遍历,动画如下:

102二叉树的层序遍历

这样就实现了层序从左到右遍历二叉树。

代码如下:这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了

c++代码如下:

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

 

107--将102的结果reverse即可;

C++代码:

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode*> que;
        if (root != NULL) que.push(root);
        vector<vector<int>> result;
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        reverse(result.begin(), result.end()); // 在这里反转一下数组即可
        return result;

    }
};

199--二叉树的右视图

层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

C++代码:

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
         vector<int>result;
         queue<TreeNode*>que;
         if (root != nullptr) { que.push(root); }
         while (!que.empty())
         {
             int size = que.size();
             for (int i = 0; i < size; i++)
             {
                TreeNode* cur = que.front();
                que.pop();
                if (i == size - 1) { result.push_back(cur->val); }
                if (cur->left) { que.push(cur->left); }
                if (cur->right) { que.push(cur->right); }
             }
         }
         return result;
    }
};

637--二叉树的层平均值

本题就是层序遍历的时候把一层求个总和在取一个均值。

C++代码:

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*>que;
         vector<double>result;
         if (root != nullptr) { que.push(root); }
         while (!que.empty())
         {            
             int size = que.size();
             double sum = 0;
             for (int i = 0; i < size; i++)
             {
                 TreeNode* cur = que.front();
                 que.pop();
                 sum += cur->val;
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
             }
             sum /= size;
             result.push_back(sum);
         }
         return result;
    }
};

429. N 叉树的层序遍历

这道题依旧是模板题,只不过一个节点有多个孩子了

C++代码:

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*>que;
         vector<vector<int>>result;
         if (root != nullptr) { que.push(root); }
         while (!que.empty())
         {
             int size = que.size();
             vector<int>tmp;
             for (int i = 0; i < size; i++)
             {
                 Node* cur = que.front();
                 tmp.push_back(cur->val);
                 que.pop();
                 int vsize = cur->children.size();
                 for(int j=0;j<vsize;j++)
                 {
                    if (cur->children[j]) {que.push(cur->children[j]);}
                 }
             }
             result.push_back(tmp);
         }
         return result;
    }
};

515.在每个树行中找最大值

层序遍历,取每一层的最大值

C++代码:

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*>que;
         vector<int>result;
         if (root != nullptr) 
         { 
             que.push(root); 
         }
         while (!que.empty())
         {
             int max = que.front()->val;
             int size = que.size();           
             for (int i = 0; i < size; i++)
             {
                 TreeNode* cur = que.front();
                 if (max < (cur->val)) { max = cur->val; }
                 que.pop();
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
             }
             result.push_back(max);
         }
         return result;
    }
};

116.填充每个节点的下一个右侧节点指针

思路

本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了

C++代码:

class Solution {
public:
    Node* connect(Node* root) {
         queue<Node*>que;
         if (root != nullptr) { que.push(root); }
         while (!que.empty())
         {
             int size = que.size();
             Node* pre;
             Node* cur;
             for (int i = 0; i < size; i++)
             {
                 if (i == 0) 
                 {
                     pre = que.front();
                     que.pop();
                     cur = pre;
                 }
                 else
                 {
                     cur = que.front();
                     que.pop();
                     pre->next = cur;
                     pre = pre->next;
                 }
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
             }
             pre->next = nullptr;
         }
         return root;
    }
};

117.填充每个节点的下一个右侧节点指针II

思路

这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道

C++代码:

class Solution {
public:
    Node* connect(Node* root) {
         queue<Node*>que;
         if (root != nullptr) { que.push(root); }
         while (!que.empty())
         {
             int size = que.size();
             Node* pre;
             Node* cur;
             for (int i = 0; i < size; i++)
             {
                 if (i == 0) 
                 {
                     pre = que.front();
                     que.pop();
                     cur = pre;
                 }
                 else
                 {
                     cur = que.front();
                     que.pop();
                     pre->next = cur;
                     pre = pre->next;
                 }
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
             }
             pre->next = nullptr;
         }
         return root;
    }
};

104.二叉树的最大深度

思路

使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。

在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度,如图所示:

层序遍历

所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决的。

C++代码如下:

class Solution {
public:
    int maxDepth(TreeNode* root) {
        queue<TreeNode*>que;
         int depth = 0;
         if (root != nullptr) 
         {
            que.push(root);
         }
         while (!que.empty())
         {
             int size = que.size();
             for (int i = 0; i < size; i++)
             {
                 TreeNode* cur = que.front();
                 que.pop();
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
             }
             depth++;
         }
         return depth;
    }
};

111.二叉树的最小深度

思路

相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

代码如下:(详细注释)

class Solution {
public:
    int minDepth(TreeNode* root) {
        queue<TreeNode*>que;
         int depth = 0;
         if (root != nullptr){que.push(root);}
         else {return depth;}                           
         while (!que.empty())
         {
             int size = que.size();
             depth++;
             for (int i = 0; i < size; i++)
             {
                 TreeNode* cur = que.front();
                 que.pop();
                 if (cur->left) { que.push(cur->left); }
                 if (cur->right) { que.push(cur->right); }
                 if (cur->left == nullptr && cur->right == nullptr)
                 {
                     return depth;
                 }
             }             
         }
         return depth;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1883_把FreeRTOS中的heap_4作为一个通用模块使用并初步测试

全部学习汇总&#xff1a; GreyZhang/c_units: A small piece of code which can be reuse anywhere, I call it a unit. This is a collection of unit in C language! Ok, yes, it would be my toolbox. (github.com) 在嵌入式&#xff0c;尤其是控制类的嵌入式中很少有mallo…

SUDA-计算机网路-期末复习提纲

写在前面 帮苏大的同学整理的计网复习材料&#xff0c;用的是他们老师划定的范围。 1.负责互联网协议开发、标准制定、地址分配的国际组织名称及其主要职责 (1) 地址支持组织&#xff08;ASO&#xff09;负责IP地址系统的管理。 (2) 域名支持组织&#xff08;DNSO&#xff09;…

CMU15-445-Spring-2023-Project #1 - 前置知识(lec01-06)

Lecture #01_ Relational Model & Relational Algebra Databases 数据库是相互关联的数据的有组织集合&#xff0c;对现实世界的某些方面进行建模。区别于DBMS&#xff08;MySQL、Oracle&#xff09;。 Flat File Strawman 数据库以CSV文件的形式存储&#xff0c;并由D…

非常漂亮的外贸网站完整代码,适合机械加工和金属零件等领域。

非常漂亮的外贸网站完整代码&#xff0c;适合机械加工和金属零件等领域。整站代码&#xff0c;上传到服务器虚拟主机即可使用。 独家原创资源。源码是asp开发的&#xff0c;数据库是access&#xff0c;主流的虚拟主机空间都支持asp&#xff0c;直接上传就可以使用。 站长保证…

PTA✨C语言 就不告诉你

7-7 就不告诉你 分数 15 全屏浏览题目 切换布局 作者 CHEN, Yue 单位 浙江大学 做作业的时候&#xff0c;邻座的小盆友问你&#xff1a;“五乘以七等于多少&#xff1f;”你应该不失礼貌地围笑着告诉他&#xff1a;“五十三。”本题就要求你&#xff0c;对任何一对给定的正…

Spring MVC自定义类型转换器!!!

使用场景 在index.jsp里面添加日期类型 <form action"account/saveAccount" method"post">账户名称&#xff1a;<input type"text" name"name"><br/>账户金额&#xff1a;<input type"text" name&quo…

CTF-PWN-栈溢出-中级ROP-【栈迁移】

文章目录 栈迁移具体流程 VNCTF 2023 traveler libc-2.27检查源码main函数![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/386c35c30f854434ae43667b9473c58a.png)全局变量地址局部变量地址 PIE保护开启PIE关闭PIE 思路exp 栈迁移参考 栈迁移参考 栈迁移 顾名思义…

充分利用城市闲置空地,建造舒适的气膜运动馆

在城市土地紧张的背景下&#xff0c;气膜建筑以其轻盈灵动的特性&#xff0c;成为利用闲置空地的理想选择。建造舒适的气膜运动馆不仅提升了城市空间利用效率&#xff0c;更为全民健身搭建了一座充满活力的乐园&#xff0c;为城市生活注入了新的活力和福音。 解决城市土地紧张的…

将Llama2上下文长度扩展100倍;效率更高的SeTformer;LLM准确度基本不变加速1.56×;FreeTalker

本文首发于公众号&#xff1a;机器感知 将Llama2上下文长度扩展100倍&#xff1b;效率更高的SeTformer&#xff1b;LLM准确度基本不变加速1.56&#xff1b;FreeTalker Latte: Latent Diffusion Transformer for Video Generation 本文使用Latent Diffusion Transformer(Latte…

让开发改bug全靠催?分享6个实用技巧

测试小伙伴们&#xff0c;你们有遇到下图的情况吗&#xff1f; ​ 这张图其实还算“温柔”的&#xff0c;其实有些情况下&#xff0c;某些测试人员或者开发人员脾气大的可能撕逼或者快干架。所以如何和开发有效沟通&#xff0c;并高效劝说开发改掉bug是一门学问&#xff0c;以…

阿里云服务器e实例和云服务器u1实例有什么区别?

阿里云服务器u1和e实例有什么区别&#xff1f;ECS通用算力型u1实例是企业级独享型云服务器&#xff0c;ECS经济型e实例是共享型云服务器&#xff0c;所以相比较e实例&#xff0c;云服务器u1性能更好一些。e实例为共享型云服务器&#xff0c;共享型实例采用非绑定CPU调度模式&am…

【C++入门到精通】异常 | 异常的使用 | 自定义异常体系 [ C++入门 ]

阅读导航 引言一、C异常的概念二、异常的使用1. 异常的抛出和捕获&#xff08;1&#xff09;throw&#xff08;2&#xff09;try-catch&#xff08;3&#xff09;catch(. . .)&#xff08;4&#xff09;异常的抛出和匹配原则&#xff08;5&#xff09;在函数调用链中异常栈展开…

Java项目:112SSM在线电影订票系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 在线电影订票系统基于SpringSpringMVCMybatis开发&#xff0c;系统分为前台和后台&#xff0c;前台主要用来用户浏览电影信息&#xff0c;订票&#xff0c…

C/C++学习笔记 vcpkg使用备忘及简要说明

一、简述 vcpkg 是一个免费的 C/C 包管理器&#xff0c;用于获取和管理库。从 1500 多个开源库中进行选择&#xff0c;一步下载并构建&#xff0c;或者添加您自己的私有库以简化构建过程。由 Microsoft C 团队和开源贡献者维护。 官方教程 vcpkg 文档 | Microsoft Learnvcpkg …

day-04 字符串中的额外字符

思路 动态规划&#xff0c;每个字符要么额外要么不是额外 解题方法 int[] dp new int[n1]; dp[i] 表示从字符串开头到字符串索引i位置的最少额外字符数 dp[i 1] Math.min(dp[i 1], dp[j]) dp[j]表示假设s第i个字符不是额外的&#xff0c;可能等于dp[i 1]&#xff0c;也可…

GPS 模拟器

GPS 工具包&#xff1a;https://www.ni.com/es/support/downloads/software-products/download.gnss-test-toolkit.html#333303 GPS-SDR-SIM&#xff1a;https://github.com/osqzss/gps-sdr-sim GPS LabVIEW &#xff1a;http://mikioblog.dolphinsystem.jp/2017/08/gps-sdr-si…

Presto大数据学习网站:让你轻松驾驭大数据处理!

介绍&#xff1a;Presto是一个由Facebook开源的分布式SQL查询执行引擎&#xff0c;它被设计用于处理各种规模的数据并进行快速分析查询。这个引擎具有优秀的兼容性&#xff0c;可以支持众多的数据源&#xff0c;包括但不限于HDFS、关系型数据库管理系统&#xff08;RDBMS&#…

JVM的FastThrow优化机制

前言&#xff1a; 前一阵子&#xff0c;在公司排查线上问题发现&#xff1a;出问题的方法报空指针异常&#xff0c;但是没有异常堆栈信息和Message。我一开始以为是代码中做了处理&#xff0c;但是经过翻阅代码发现不是。最后一番查找资料&#xff0c;这种现象是JVM的一种优化机…

C# 日期转换“陷阱”

在 C# 中&#xff0c;日期转换可能会遇到一些陷阱。以下是一些常见的陷阱和如何避免它们&#xff1a; 时区问题 日期和时间通常与时区相关&#xff0c;但在转换时可能会忽略或混淆时区信息。确保在转换日期时始终考虑到时区&#xff0c;并使用正确的时区进行转换。 DateTime…

npm、pnpm和yarn 的区别

包管理工具是JavaScript开发中不可或缺的一部分&#xff0c;它们可以帮助我们方便地安装、更新、删除和管理项目所依赖的各种库和模块。 目前&#xff0c;最流行的包管理工具有npm、yarn和pnpm&#xff0c;它们各有各的特点和优劣势。 本文将试着对这三个工具进行全面的对比。…