LeetCode:经典题之102、103题解及延伸|双端队列Deque|树的简介|二叉树中BFS与层序遍历的关系

系列目录

88.合并两个有序数组
52.螺旋数组
567.字符串的排列
643.子数组最大平均数
150.逆波兰表达式
61.旋转链表
160.相交链表
83.删除排序链表中的重复元素
389.找不同
1491.去掉最低工资和最高工资后的工资平均值
896.单调序列
206.反转链表
92.反转链表II
141.环形链表
142.环型链表
21.合并两个有序列表
24.两辆交换链表中的节点
876.链表的中间节点
143. 重排链表
2.两数相加
445.两数相加II


目录

  • 系列目录
  • 102. 二叉树的层序遍历
  • 103. 二叉树的锯齿形层序遍历
    • 双端队列Deque
    • BFS与层序遍历


102. 二叉树的层序遍历

🌟队列+BFS/层序遍历

原题链接


C++
若未特殊标明,以下题解均写用C++

/*** 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) {}* };*/
// #include <queue>  
// #include <vector>  
class Solution {  
public:  vector<vector<int>> levelOrder(TreeNode* root) {  vector<vector<int>> ans;  if (root == nullptr)return ans;  queue<TreeNode*> cur;  cur.push(root);  while (!cur.empty()) {  int size = cur.size(); // 当前层的节点数  vector<int> vals; // 存储当前层的节点值  for (int i = 0; i < size; ++i) {  TreeNode* node = cur.front();  cur.pop();  vals.push_back(node->val);  if (node->left) {  cur.push(node->left);  }  if (node->right) {  cur.push(node->right);  }  }  ans.push_back(vals); // 将当前层的节点值添加到答案中  }  return ans;  }  
};





103. 二叉树的锯齿形层序遍历

🌟队列+双端队列+BFS/层序遍历

原题链接

本题实为102.二叉树的层序遍历变种题


C++
若未特殊标明,以下题解均写用C++

/*** 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) {}* };*/
class Solution {
public:vector<vector<int>> zigzagLevelOrder(TreeNode* root) {// 因为最终返回的结果是 集合套集合// 定义一个二维向量 res 存放结果vector<vector<int>> res;if (!root)return res;bool isOrderLeft = true;// 初始化普通队列 存放二叉树的树状节点// nodeQueuequeue<TreeNode*> nq;// 将根节点入队 能正常开始循环nq.push(root);while (!nq.empty()) {// 初始化双端队列 以便不同次序输出每一层的树节点值// floorListDequedeque<int> fld;int size = nq.size();for (int i = 0; i < size; i ++) {auto node = nq.front();// 用完当前的node 出队nq.pop();if (isOrderLeft) {// int 类型的双端队列 fld// 从左往右——从队尾入队fld.push_back(node->val);} else {// 从右往左——从队头入队fld.push_front(node->val);}if (node->left) {nq.push(node->left);}if (node->right) {nq.push(node->right);}} // for_endres.emplace_back(vector<int>{fld.begin(), fld.end()});isOrderLeft = !isOrderLeft;} // while_endreturn res;}
};





双端队列Deque

双端队列(Deque,全称double-ended queue)是一种具有队列和栈的性质的抽象数据类型
允许我们在两端进行插入和删除操作,即可以从头部(front)或尾部(back)添加或移除元素
在C++中,std::deque是标准模板库(STL)提供的一个双端队列的实现
不过,为了深入理解双端队列的工作原理,我们可以尝试自己实现一个简单的双端队列
以下是一个简单的双端队列的C++实现,我们将使用动态数组(例如,通过std::vector)来存储元素,并提供基本的双端队列操作,如push_front、push_back、pop_front、pop_back、front、back

#include <iostream>  
#include <vector>  
#include <stdexcept> // For std::out_of_range  template<typename T>  
class MyDeque {  
private:  std::vector<T> data;  public:  // 向队尾添加元素  void push_back(const T& value) {  data.push_back(value);  }  // 向队首添加元素  void push_front(const T& value) {  data.insert(data.begin(), value);  }  // 从队尾移除元素  void pop_back() {  if (data.empty()) {  throw std::out_of_range("Deque is empty");  }  data.pop_back();  }  // 从队首移除元素  void pop_front() {  if (data.empty()) {  throw std::out_of_range("Deque is empty");  }  data.erase(data.begin());  }  // 访问队首元素  T& front() {  if (data.empty()) {  throw std::out_of_range("Deque is empty");  }  return data.front();  }  // 访问队尾元素  T& back() {  if (data.empty()) {  throw std::out_of_range("Deque is empty");  }  return data.back();  }  // 判断双端队列是否为空  bool empty() const {  return data.empty();  }  // 获取双端队列的大小  size_t size() const {  return data.size();  }  
};  int main() {  MyDeque<int> myDeque;  myDeque.push_back(10);  myDeque.push_front(5);  myDeque.push_back(15);  std::cout << "Front element: " << myDeque.front() << std::endl;  std::cout << "Back element: " << myDeque.back() << std::endl;  myDeque.pop_front();  std::cout << "After pop_front, front element: " << myDeque.front() << std::endl;  myDeque.pop_back();  std::cout << "After pop_back, back element: " << myDeque.back() << std::endl;  return 0;  
}

⚠️注意事项
性能: 虽然以上代码实现起来简单易懂,但在某些操作上(如push_frontpop_front),由于std::vector的特性,可能需要移动大量元素,因此性能可能不是最优的

错误处理: 在实现中,我使用了std::out_of_range异常来处理尝试在空双端队列上进行popfront/back访问的情况
这是一种常见的错误处理方式,但你也可以选择其他方式,如返回特殊值或设置错误标志

功能扩展: 你可以根据需要扩展这个类,比如 添加迭代器支持、更复杂的元素访问方法(如通过索引访问)等





树(Tree)是一种特殊的图(Graph)
具体来说,树是一种无环的连通图


特性如下:

  • 无环(Acyclic): 树中不包含任何环 ,即从一个节点到另一个节点存在唯一的一条路径
  • 连通(Connected): 树中的任意两个节点都通过边(或路径)相连
  • 无向图: 虽然树的概念也可以扩展到有向图(如二叉树),但在大多数情况下,当我们说“树”时,我们指的是无向图
  • 根节点: 虽然图不一定有根节点的概念,但树通常被定义为一个或多个特定的节点(称为根节点)以及从根节点出发的一系列边和子树
    在只有一个根节点的树中,每个节点(除了根节点本身)都有且仅有一个父节点,而每个非叶节点都可以有多个子节点
  • 叶子节点: 树中的叶子节点是没有子节点的节点
  • 路径: 树中的路径是指从一个节点到另一个节点所经过的一系列边和节点的序列,由于树是无环的,所以任意两个节点之间的路径是唯一的



BFS与层序遍历

在二叉树的遍历中,BFS和层序遍历实际上是同一个概念的不同表述方式

  • 广度优先搜索(BFS, Breadth-First Search): 一种用于图和树的遍历或搜索算法
    它从根节点开始,先访问离根节点最近的节点(即第一层),然后逐层向下访问,每层按从左到右的顺序访问节点
    对于二叉树来说,这恰好就是层序遍历
  • 层序遍历(Level-Order Traversal): 二叉树遍历的一种特殊方式,它按照树的层次从上到下、从左到右进行遍历, 通常用队列实现
    具体来说,就是先访问根节点,然后遍历根节点的左子树和右子树,接着再遍历左子树的左子树和右子树、右子树的左子树和右子树,以此类推,逐层遍历

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

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

相关文章

安全防御拓扑1

目录 实验的拓扑&#xff1a; 要求&#xff1a; 我搭建的实验拓扑 步骤&#xff1a; 创建vlan&#xff1a; 接口配置&#xff1a; 防火墙&#xff1a; 防火墙配置&#xff1a; 建立安全策略&#xff1a; 防火墙的用户&#xff1a; 办公区的市场部和研发部用户 市场部…

杰发科技AC7801 —— __attribute__指定地址存储常量

const uint8_t usFlashInitVal[] __attribute__((at(0x08002800))) {0x55,0x55,0x55,0x55,0x55};//定位在flash中&#xff0c;0x00030000开始的6个字节信息固定 注意7801的地址在8000000之后 如地址选0x00000800烧录时候报错 不知道是不是atclinktool的bug&#xff0c;使用_…

PCIe总线的序

PCIe序的要求是为了满足满足生产者/消费者模型&#xff0c;和避免死锁。可以通过配置RO和IDO使得报文通过中间路径变为宽松排序&#xff0c;但可能会带来一些违反生产者/消费者模型的问题&#xff0c;需要开发者自行保证. 生产/消费者工作流程 生产者&#xff08;FPGA板卡&am…

勒索防御第一关 亚信安全AE防毒墙全面升级 勒索检出率提升150%

亚信安全信舷AE高性能防毒墙完成能力升级&#xff0c;全面完善勒索边界“全生命周期”防御体系&#xff0c;筑造边界勒索防御第一关&#xff01; 勒索之殇&#xff0c;银狐当先 当前勒索病毒卷携着AI技术&#xff0c;融合“数字化”的运营模式&#xff0c;形成了肆虐全球的网…

【C/C++】内存相关

内存相关 1 ptmalloc ptmalloc是GNU C Library&#xff08;glibc&#xff09;中的默认内存分配器&#xff0c;广泛用于Linux系统。以下是对ptmalloc的详细解析&#xff1a; 一、概述 起源&#xff1a;ptmalloc起源于Doug Lea的malloc实现&#xff0c;并由Wolfram Gloger进行…

TG机器人搭建与部署全攻略:源码搭建技巧与实战教学

TG机器人因其高度的可定制性和广泛的应用场景&#xff0c;成为了开发者和创业者的热门选择。本文将提供一份全面的TG机器人搭建与部署攻略&#xff0c;涵盖源码搭建技巧与实战教学&#xff0c;帮助读者快速掌握TG机器人的开发与上线。 关键词 TG机器人&#xff0c;搭建&#…

数据结构(4.4)——求next数组

next数组的作用:当模式串的第j个字符失配时&#xff0c;从模式串的第next[j]的继续往后匹配 求模式串的next数组(手算) next[1] 任何模式串都一样&#xff0c;第一个字符不匹配时&#xff0c;只能匹配下一个子串&#xff0c;因此&#xff0c;往后&#xff0c;next[1]都无脑写…

Classifier-Free Guidance (CFG) Scale in Stable Diffusion

1.Classifier-Free Guidance Scale in Stable Diffusion 笔记来源&#xff1a; 1.How does Stable Diffusion work? 2.Classifier-Free Diffusion Guidance 3.Guide to Stable Diffusion CFG scale (guidance scale) parameter 1.1 Classifier Guidance Scale 分类器引导是…

达梦数据库的系统视图v$dict_cache_item

达梦数据库的系统视图v$dict_cache_item 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$DICT_CACHE_ITEM 是一个系统视图&#xff0c;用于显示字典缓存&#xff08;Dictionary Cache&#xff09;中的项信息。字典缓存是数据库中的一个重要组件&#xff0c;…

RepLKNet(CVPR 2022, MEGVII)

paper&#xff1a;Scaling Up Your Kernels to 31x31: Revisiting Large Kernel Design in CNNs official implementation&#xff1a;https://github.com/DingXiaoH/RepLKNet-pytorch 背景 卷积神经网络&#xff08;CNN&#xff09;曾经是现代计算机视觉系统中的常见选择。…

Golang | Leetcode Golang题解之第231题2的幂

题目&#xff1a; 题解&#xff1a; func isPowerOfTwo(n int) bool {const big 1 << 30return n > 0 && big%n 0 }

CentOS 7 中出现 cannot open Packages database in /var/lib/rpm 错误

转载自:https://www.jianshu.com/p/423306f43e72 # 进入 rpmdb 所在目录 [roothostbase ~]# cd /var/lib/rpm [roothostbase rpm]# ls Basenames __db.001 __db.003 Group Name Packages Requirename Sigmd5 Conflictname __db.002 Dirnames Ins…

在 vite+vue3+electron 中使用 express

文章目录 一、Vite Vue3 Electron 项目的搭建二、搭建 express 环境1、安装 express 框架所需依赖2、创建 express 项目3、配置路由4、启动 express 服务5、启动 electron 并获取数据 三、项目打包 一、Vite Vue3 Electron 项目的搭建 详细的项目构建和打包可参考另一篇文…

hung 之 softlockup hardlockup 检测

1. softlockup & hardlockup 的含义 softlockup 指的是这样一种场景&#xff1a;由于内核程序设计问题&#xff0c;导致CPU长时间关闭抢占。 hardlockup 指的是这样一种场景&#xff1a;由于内核程序设计问题&#xff0c;导致CPU时钟中断长时间禁用。 softlockup 或 har…

【UE5.1】NPC人工智能——02 NPC移动到指定位置

效果 步骤 1. 新建一个蓝图&#xff0c;父类选择“AI控制器” 这里命名为“BP_NPC_AIController”&#xff0c;表示专门用于控制NPC的AI控制器 2. 找到我们之前创建的所有NPC的父类“BP_NPC” 打开“BP_NPC”&#xff0c;在类默认值中&#xff0c;将“AI控制器类”一项设置为“…

【Diffusion学习】【生成式AI】淺談圖像生成模型 Diffusion Model 原理

文章目录 Diffusion Model 是如何运作的&#xff1f;吃额外的1个数字&#xff1a;stepDenoise 模组内部实际做的事情&#xff1a;预测noise如何训练 Noise Predictor Text-to-ImageDDPM 算法 from&#xff1a; https://www.youtube.com/watch?vazBugJzmz-o&listPLJV_el3uV…

Go 协程通道使用注意

目录 关闭channel 引入 不关闭通道是有风险的&#xff0c;主要存在两条&#xff1a; 如何优雅的关闭&#xff1f; 1.只有一个发送者 2.多个发送者 判断通道是否关闭 有缓存和无缓存的通道有什么区别&#xff1f; 错误的关闭通道 关闭channel close(chan)&#xff1a;关…

[HCTF 2018]WarmUp1

进入靶场&#xff0c;检查代码看到有source.php,访问 /source.php 读代码&#xff0c;在参数中传入 file&#xff0c;通过checkFile后&#xff0c;会加载file界面。 再看checkFile&#xff0c; 第一个判断&#xff0c;是非空并且是个字符串&#xff0c;否则返回false 第二个判…

LeetCode题练习与总结:最大间距--164

一、题目描述 给定一个无序的数组 nums&#xff0c;返回 数组在排序之后&#xff0c;相邻元素之间最大的差值 。如果数组元素个数小于 2&#xff0c;则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1: 输入: nums [3,6,9,1] 输出: 3 …

微软研发致胜策略 01:尊定基础

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1994 年发布。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Debugging the Development Process》&#xff0c;这本书详细阐述了软件开发过程中的常见问题及其解决方案&a…