LeetCode-102.题: 二叉树的层序遍历(原创)

【题目描述】

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

【题目链接】. - 力扣(LeetCode)

【解题代码】

package tree.binarytree;import java.util.*;public class LevelOrderTraversal {public static void main(String[] args) {Integer[] array = new Integer[]{1,2,3,4,null,null,5};TreeNode root = TreeNode.constructTree(array);List<List<Integer>> lists = new LevelOrderTraversal().levelOrder(root);lists.forEach(l -> System.out.println(Arrays.toString(l.toArray())));}private List<List<Integer>> levelOrder(TreeNode root) {// 特殊情况处理,如果树根节点为空,返回空列表if (root == null) return new ArrayList<>();// 定义一个队列,临时存放所访问的树节点Queue<TreeNode> queue = new LinkedList<>();// 首先将树的根节点放入队列中queue.add(root);TreeNode node;// 存储所有层节点列表的列表List<List<Integer>> lists = new ArrayList<>();// 初始化当前父节点个数为1(即根节点),以及子节点个数int curLevelCount = 1, nextLevelCount = 0;// 当前层节点列表List<Integer> list = new ArrayList<>();while (curLevelCount > 0) {// 从队列里弹出一个父节点,并将父节点数据减1node = queue.poll();curLevelCount--;// 将此父节点放入当前层节点列表list.add(node.val);// 如果此节点左子节点不为空,放入队列中,并将子节点数目加1if (node.left != null) {queue.add(node.left);nextLevelCount++;}// 如果此节点右子节点不为空,放入队列中,并将子节点数目加1if (node.right != null) {queue.add(node.right);nextLevelCount++;}// 如果当前层父节点访问完毕if (curLevelCount == 0){// 将当前层节点,拷贝到结果列表中,并进行清空lists.add(new ArrayList<>(list));list.clear();// 然后将下一层所有节点作为当前层节点,重启新一轮的遍历curLevelCount = nextLevelCount;nextLevelCount = 0;}}// 最后返回结果return lists;}
}

【解题思路】

        我们之前数据结构学习树遍历的内容,一般都是左、中、右三种遍历循序,按树的层次遍历还没处理过,需要自行思考,不能借鉴教科书了,深入反复思考,得出以下几个要点

  1. 第一层就一个节点,树的根节点,第二层就是根节点的左右子节点,第三层就是根节点的左右子节点的所有左右子节点,后面以此类推。。。
  2. 每次我们可以在队列中保存当前层的树节点,然后一一弹出,放入当前层列表中,并将其子节点放入队列中
  3. 当前层访问结束后,剩下的就是当前层的下一层所有节点。将其设置为新的当前层,反复循环处理即可

按照这个思路,很快就写出算法代码,并提交成功,解题步骤如下:

【解题步骤】

  1. 定义当前层树节点列表以及结果所有层节点列表
    // 定义一个队列,临时存放所访问的树节点
    Queue<TreeNode> queue = new LinkedList<>();
    // 存储所有层节点列表的列表
    List<List<Integer>> lists = new ArrayList<>();
  2. 定义一个队列,临时存放所访问的树节点,首先将树的根节点放入队列中
    // 定义一个队列,临时存放所访问的树节点
    Queue<TreeNode> queue = new LinkedList<>();
    // 存储所有层节点列表的列表
    queue.add(root);
  3. 初始化当前父节点个数为1(即根节点),以及子节点个数
    int curLevelCount = 1, nextLevelCount = 0;
  4. 依次遍历当前层所有节点,一一从队列里弹出,放入当前层节点列表
    while (curLevelCount > 0) {// 从队列里弹出一个父节点,并将父节点数据减1node = queue.poll();curLevelCount--;// 将此父节点放入当前层节点列表list.add(node.val);
  5. 将其左右子节点作为下一层节点加入队列中
    // 如果此节点左子节点不为空,放入队列中,并将子节点数目加1
    if (node.left != null) {queue.add(node.left);nextLevelCount++;
    }
    // 如果此节点右子节点不为空,放入队列中,并将子节点数目加1
    if (node.right != null) {queue.add(node.right);nextLevelCount++;
    }
  6. 如果当前层所有节点遍历完毕,将当前层节点,拷贝到结果列表中,并进行清空,然后将下一层所有节点作为当前层节点,重启新一轮的遍历
    ​
    // 如果当前层父节点访问完毕
    if (curLevelCount == 0){// 将当前层节点,拷贝到结果列表中,并进行清空lists.add(new ArrayList<>(list));list.clear();// 然后将下一层所有节点作为当前层节点,重启新一轮的遍历curLevelCount = nextLevelCount;nextLevelCount = 0;
    }​
  7. 最后返回结果
    return lists;

【思考总结】

  1. 这道理的关键点在于“自顶向下,一层接一层交替访问树节点”;
  2. 算法设计时,可以考虑最简单的情况,试探思考其运行逻辑应该是什么样的
  3. 还是要有精细化的逻辑思维,层次分明,这样在复杂的逻辑也不会乱;
  4. LeetCode解题之前,可以看提示,但一定不要看题解,看了就“破功”了!

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

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

相关文章

【C语言】InfiniBand驱动mlx4_init和mlx4_cleanup

一、中文注释 Linux内核模块的初始化和清理过程&#xff0c;针对一个称为mlx4的网络设备驱动。以下是代码的逐行中文注释&#xff1a; static int __init mlx4_init(void) {int ret;if (mlx4_verify_params())return -EINVAL; // 检查设备参数是否有效&#xff0c;无效则返回…

抖店月销过万的爆单技巧,新手轻松月入1w+,附抖店学习资料!

我是电商珠珠 抖店开通之后&#xff0c;怎么才能快速出单是很多新手小伙伴困扰的问题。其实想要运营好抖店一点都不难&#xff0c;我做抖店也有三年多时间了&#xff0c;接下来我说的每一步&#xff0c;不管是有货源还是无货源的都适用。 1、铺货低价福利款 店铺开好之后&am…

Java Web开发---复试Tips复习

***********&#xff08;自用&#xff0c;摘录自各种文章和自己总结&#xff09;********** 小知识点理解 Web Web应用开发主要是基于浏览器的应用程序开发。一个Web应用由多部分组成 java web就是用java语言开发出可在万维网上浏览的程序 Web应用程序编写完后&#xff0c;…

如何在Windows上使用Docker,搭建一款实用的个人IT工具箱It- Tools

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

JavaScript极速入门(2)

JQuery W3C标准给我们提供了一系列函数,让我们可以操作: 网页内容 网页结构 网页样式 但是原生的JavaScript提供的API操作DOM元素时,代码比较繁琐,冗长.我们学习使用JQuery来操作页面对象. JQuery是一个快速,简洁且功能丰富的JavaScript框架,于2006年发布.它封装JavaScript常…

Charles抓包工具使用

Charles简介 Charles是一款基于HTTP协议的代理服务器和HTTP监视器&#xff0c;通过将自己设置为电脑或浏览器的网络访问代理&#xff0c;能够截取请求和请求结果&#xff0c;从而达到分析抓包的目的。它允许开发者查看所有连接互联网的HTTP通信&#xff0c;包括请求、响应和HTT…

1.5如何缓解图像分类任务中训练数据不足带来的问题?

1.5 图像数据不足时的处理方法 场景描述 在机器学习中&#xff0c;绝大部分模型都需要大量的数据进行训练和学习(包括有监督学习和无监督学习)&#xff0c;然而在实际应用中经常会遇到训练数据不足的问题。 比如图像分类&#xff0c;作为计算机视觉最基本的任务之一&#xff0…

万字详解,Java实现低配版线程池

文章目录 1.什么是线程池2.线程池的优势3.原理4.代码编写4.1 阻塞队列4.2 ThreadPool线程池4.3 Worker工作线程4.4 代码测试 5. 拒绝策略5.1 抽象Reject接口5.2 BlockingQueue新增tryPut方法5.3 修改ThreadPool的execute方法5.4 ThreadPool线程池构造函数修改5.5 拒绝策略实现1…

虾皮、lazada店铺运营攻略,如何搭建高效、稳定的自养号测评系统

随着电子商务的蓬勃发展&#xff0c;越来越多的人选择在虾皮这样的电商平台上开设店铺&#xff0c;以实现创业梦想。但如何在众多店铺中脱颖而出&#xff0c;成为消费者的首选?本文将为您详细解答“怎么样做好虾皮店铺”&#xff0c;并提供一些实用的运营建议。 一、怎么样做…

【grafana】Grafana Image Renderer插件获取grafana仪表盘图片(docker方式、python爬虫)

1、编写docker-compose.yml文件 #如果你已启动grafana容器&#xff0c;只需修改docker-compose.yml&#xff0c;在grafana添加环境变量&#xff0c;grafana-image-renderer插件的服务&#xff0c;官网地址&#xff1a;Grafana Image Renderer plugin for Grafana | Grafana L…

C#,煎饼排序问题(Pancake Sorting Problem)算法与源代码

1 煎饼排序问题 给定一个未排序的数组&#xff0c;任务是对给定数组进行排序。您只能在阵列上执行以下操作。 翻转&#xff08;arr&#xff0c;i&#xff09;&#xff1a;将数组从0反转为i 示例&#xff1a; 输入&#xff1a;arr[]{23、10、20、11、12、6、7} 输出&#xff1a…

基于51单片机风速仪风速测量台风预警数码管显示

基于51单片机风速仪风速测量报警数码管显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告&#x1f517;6. 下载链接资料下载链接&#xff1a; 基于51单片机风速仪风速测量报警数码管显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图…