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

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

题目一:

算法原理:

层序遍历是经典的宽搜,即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://www.xdnf.cn/news/20281.html

相关文章:

  • Doris 数据仓库例子
  • OpenCV C++ 色彩空间详解:转换、应用与 LUT 技术
  • 一文详解深度学习中神经网络的各层结构与功能!
  • SQL-DML
  • 计算机网络4 第四章 网络层——网络间的通信问题(省际之间如何规划信件运输路线)
  • 酒店实习生转正信息调整编程实现(Python字典应用基础题)
  • 【yolo】YOLOv8 训练模型参数与多机环境差异总结
  • Kafka面试精讲 Day 8:日志清理与数据保留策略
  • Grafana 导入仪表盘失败:从日志排查到解决 max\_allowed\_packet 问题
  • 汽车软件研发智能化:AI在CI/CD中的实践
  • 实践指南:利用衡石AI Data Agent实现自然语言驱动的指标开发与归因
  • 【最新版】发烧级完美解码播放器PureCodec v2025.08.29 中文免费版_电脑播放器影音解码包
  • 基于51单片机WIFI智能家居系统设计
  • 相机刮除拜尔阵列
  • 使用海康机器人相机SDK实现基本参数配置(C语言示例)
  • Linux查看相机支持帧率和格式
  • Linux系统安全加固:构建云计算安全的第一道防线
  • 迁移学习-ResNet
  • VBA 中使用 ADODB 操作 SQLite 插入中文乱码问题
  • JVM新生代和老生代比例如何设置?
  • Vue 3 项目中引入 Iconify
  • Spring Boot 和 Spring Cloud: 区别与联系
  • Oracle到ClickHouse:异构数据库ETL的坑与解法
  • HTML 各种事件的使用说明书
  • Spring Boot AOP:优雅解耦业务与非业务逻辑的利器
  • 如何将 Android 设备的系统底层日志(如内核日志、系统服务日志等)拷贝到 Windows 本地
  • WeaveFox AI智能开发平台介绍
  • Docker部署Drawnix开源白板工具
  • 【RelayMQ】基于 Java 实现轻量级消息队列(六)
  • React Fiber 风格任务调度库