当前位置: 首页 > news >正文

系统学习算法 专题十八 队列+宽搜

题目一:

算法原理:

层序遍历是经典的宽搜,即BFS搜索方式,往往和队列搭配使用

这道题的步骤为,先将头结点放进队列,然后去遍历此时队列中所有的元素,然后在遍历队列的过程中,又将被遍历的元素的所有子节点全部加进队列,当此次遍历结束后,就会将下一层的元素全部放进队列中,然后将本次遍历的所有元素放进一个顺序表中,再加入返回顺序表中即可

代码:

class Solution {public List<List<Integer>> levelOrder(Node root) {//结果集List<List<Integer>> ret=new ArrayList<>();//特判if(root==null){return ret;}//添加根结点Queue<Node> q=new LinkedList<>();q.offer(root);//宽搜while(!q.isEmpty()){int sz=q.size();List<Integer> list=new ArrayList<>();//遍历本层的所有元素for(int i=0;i<sz;i++){Node t=q.poll();list.add(t.val);//将下一层元素放进队列for(Node child:t.children){if(child!=null){q.offer(child);}}}//将本层元素存进一个顺序表中并放进结果集ret.add(list);}//返回结果return ret;}
}

题目二:

算法原理:

题意很简单,跟层序遍历差不多,只是变成了左右交替的顺序进行层序遍历,因此需要一个标记位来记录本层的遍历顺序是从左往右还是从右往左的,如果是从右往左,则在原来的层序遍历的基础上,添加一个逆序操作即可

代码:

class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {//结果集List<List<Integer>> ret=new ArrayList<>();//特判if(root==null){return ret;}Queue<TreeNode> q=new LinkedList<>();//记录本次是往左还是往右int flag=0;q.offer(root);//宽搜while(!q.isEmpty()){int sz=q.size();List<Integer> list=new ArrayList<>();//遍历本层元素for(int i=0;i<sz;i++){TreeNode node=q.poll();list.add(node.val);//将下一层元素放进队列if(node.left!=null){q.offer(node.left);}if(node.right!=null){q.offer(node.right);}}//如果是从右往左的if(flag==1){//逆序Collections.reverse(list);flag=0;}else{flag=1;}//将本层元素放进顺序表并加入到结果集ret.add(list);}return ret;}
}

题目三:

算法原理:

这道题题意有一点困难,首先需要注意的是,这棵树是当作满二叉树看的,即虽然空结点没有显示,但也算作一个结点,并计入该层的长度,然后就是每一层的长度,不能简单的直接套用满二叉树每一层的长度公式,因为题目要求的每层长度是指从最左到最右的非空结点之间的长度

第一反应肯定是暴力,即采用层序遍历,然后将所有结点都扔进去,包括空结点,每次遍历一层后,就统计一下该层的长度,当层序遍历结束后,答案也就出来了

理论可行,但是会空间溢出,因为空间太大了,比如这一层有值的结点只有最左边的一个结点,和最右边的一个结点,当高度足够大的时候,中间要存的空结点足够多,而且每往下遍历一层,空间开销都是呈指数级增长的

这时解决这个问题,就需要利用二叉树的相关公式,即父子孩子的下标计算,即如果父结点的下标为x,那么其左孩子的下标为2x,右孩子的下标为2x+1

所有根据这个公式,根本不需要存储空结点,只需要将最右有值结点的下标减去最左有值结点的下标再加1即可

比如这颗树,计算第四层的长度,就直接通过15-8+1=7即可计算出这一层的长度

这样解决了空间开销溢出,但是会出现下标溢出的情况

因为是二叉树,当树的高度假设为1000,那么最右的结点下标就为2^1000,就会出现超出整数类型的最大值,造成溢出,当溢出后就会变为负数

假设最右结点的下标溢出后为-126,最左结点的下标没有溢出为127,那么套用公式则为-126-127+1=-252,但是明明长度应该是127+3溢出后为-126,长度明明是4

其实Java系统中计算不是这样计算的,而是会进行求模,即表明上是-126-127=-253,但其实还要再模256,即-253%256=3,即-126-127=3

又因为题目说了答案将会在32位带符号整数范围内,所以不可能使得两个结点的差值超过一圈,所以即使溢出也不会造成答案错误

代码:

class Solution {public int widthOfBinaryTree(TreeNode root) {//用数组模拟队列List<Pair<TreeNode,Integer>> q=new ArrayList<>();//添加头结点q.add(new Pair<TreeNode,Integer>(root,1));//结果int ret=0;//宽搜while(!q.isEmpty()){//更新长度Pair<TreeNode,Integer> t1=q.get(0);Pair<TreeNode,Integer> t2=q.get(q.size()-1);ret=Math.max(t2.getValue()-t1.getValue()+1,ret);//下一层的结点List<Pair<TreeNode,Integer>> tmp=new ArrayList<>();for(Pair<TreeNode,Integer> t:q){TreeNode node=t.getKey();int index=t.getValue();if(node.left!=null){tmp.add(new Pair<TreeNode,Integer>(node.left,2*index));}if(node.right!=null){tmp.add(new Pair<TreeNode,Integer>(node.right,2*index+1));}}//更新队列q=tmp;}//返回结果return ret;}
}

其中Pair是一个键值对的数据结构,类似于哈希表

题目四:

算法原理:

题意很简单,就是找出每层结点中的最大值,并存进数组中,直接用层序遍历即可

代码:

class Solution {public List<Integer> largestValues(TreeNode root) {//结果集List<Integer> list=new ArrayList<>();Queue<TreeNode> q=new LinkedList<>();//特判if(root==null){return list;}//添加头结点q.offer(root);//层序遍历while(!q.isEmpty()){int size=q.size();int max=Integer.MIN_VALUE;for(int i=0;i<size;i++){TreeNode node=q.poll();//找最大值max=Math.max(max,node.val);if(node.left!=null){q.offer(node.left);}if(node.right!=null){q.offer(node.right);}}//将这一层的最大值添加到结果集list.add(max);}//返回结果集return list;}
}

文章转载自:

http://A81aZBBW.cLybn.cn
http://xd8Vz3XM.cLybn.cn
http://frQ2kbKm.cLybn.cn
http://qH8W1uwH.cLybn.cn
http://7m3pH08V.cLybn.cn
http://BI50UhHv.cLybn.cn
http://m8EiZ4oz.cLybn.cn
http://nLv8ehOZ.cLybn.cn
http://16LXRdiH.cLybn.cn
http://XASGlgAF.cLybn.cn
http://jHnWxY8J.cLybn.cn
http://qwlju7TU.cLybn.cn
http://zlIW9FK8.cLybn.cn
http://sMjXErWm.cLybn.cn
http://rsjOYj1l.cLybn.cn
http://0b4NrjsI.cLybn.cn
http://ZGPTCAyI.cLybn.cn
http://9E0TagnI.cLybn.cn
http://a0LXGASz.cLybn.cn
http://XGqkm3P2.cLybn.cn
http://BlATkuV9.cLybn.cn
http://cge5dVgh.cLybn.cn
http://qrrNQo3n.cLybn.cn
http://xmJeaKqq.cLybn.cn
http://M977MGax.cLybn.cn
http://FVLEhUQf.cLybn.cn
http://YtZMoPWr.cLybn.cn
http://JuLeKPh1.cLybn.cn
http://EvYxfIUz.cLybn.cn
http://2AnKaSOJ.cLybn.cn
http://www.dtcms.com/a/369280.html

相关文章:

  • 【c++】c++第一课:命名空间
  • Graphpad 绘图(二):小鼠生存曲线绘制与数据记录分析详解
  • DNS基本功能搭建
  • C++Primerplus 编程练习 第十二章
  • 看见世界的另一种可能:Deepoc星眸(StarGaze)如何为视障生活带来曙光
  • Springboot实现国际化(MessageSource)
  • 告别Qt Slider!用纯C++打造更轻量的TpSlider组件
  • 数字孪生赋能:智能制造如何实现从“经验驱动”到“数据驱动”?
  • 穿越市场迷雾:如何在经济周期中保持理性与长期视角
  • Mac M4环境下基于VMware Fusion虚拟机安装Ubuntu24.04 LTS ARM版
  • Vue基础知识-脚手架开发-使用Axios发送异步请求+代理服务器解决前后端分离项目的跨域问题
  • 苍穹外卖 day03
  • 【学习笔记】解决 JWT 解析报错:Claims claims = JwtUtil.parseJWT(...) Error Code 401(token过期)
  • linux下快捷删除单词、行的命令
  • AI提示词增强丨用EARS语法进行产品原子化拆解
  • 概率论第三讲——多维随机变量及其分布
  • 重大更新Claude更新用户协议把中国列为敌对国家
  • 移植Qt4.8.7到ARM40-A5
  • C++语言编程规范-初始化和类型转换
  • Gartner发布2025年数据安全领域的先锋厂商:GenAI和量子计算时代的数据安全创造性技术、产品和服务
  • 微前端架构:解构前端巨石应用的艺术
  • uniapp开发前端静态视频界面+如何将本地视频转换成网络地址
  • EI会议:第三届大数据、计算智能与应用国际会议(BDCIA 2025)
  • 9.5C++作业
  • 数据库基础知识——聚合函数、分组查询
  • MySQL 综合练习
  • 基于cornerstone3D的dicom影像浏览器 第三章 拖拽seriesItem至displayer上显示第一张dicom
  • 用户眼中的VR自来水厂之旅
  • 数据安全成焦点:基于Hadoop+Spark的信用卡诈骗分析系统实战教程
  • 瑞芯微RV1126目标识别算法Yolov8的部署应用