题目信息

  • 时间: 2019-06-25

  • 题目链接:Leetcode

  • tag:双端队列

  • 难易程度:中等

  • 题目描述:

    请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

示例1:

给定二叉树: [3,9,20,null,null,15,7],

    3
/ \
9 20
/ \
15 7

返回其层次遍历结果:

[
[3],
[20,9],
[15,7]
]

提示

1.节点总数 <= 1000

解题思路

本题难点

二叉树层序遍历,每层遍历顺序都发生变化,奇数层逆序

具体思路

层序遍历 + 双端队列

  • 操作:利用双端队列的两端皆可添加元素的特性,设打印列表(双端队列) level ,并规定

    • 奇数层 则添加至 level 尾部
    • 偶数层 则添加至 level 头部

代码

class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//当树的根节点为空,则直接返回空列表 []
if(root == null){
return new ArrayList<>(0);
}
//打印结果空列表 res
List<List<Integer>> res = new ArrayList<>();
//包含根节点的双端队列 queue
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
//BFS 循环: 当 queue 为空时跳出;
while(!queue.isEmpty()){
//新建列表 level ,用于临时存储当前层打印结果;
LinkedList<Integer> level = new LinkedList<>();
//当前层打印循环: 循环次数为当前层节点数(即 queue 长度)
for(int i = queue.size(); i > 0; i--){
//出队: 队首元素出队,记为 node
TreeNode node = queue.poll();
//打印: 若为奇数层,将 node.val 添加至 level 尾部;否则,添加至 level 头部;
if(res.size() % 2 == 0){
level.addLast(node.val);
}else{
level.addFirst(node.val);
}
//添加子节点: 若 node 的左(右)子节点不为空,则加入队列queue;
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
//将当前层结果列表level 并添加入结果列表 res中
res.add(level);
}
//返回打印结果列表 res 即可
return res;
}
}

复杂度分析:

  • 时间复杂度 O(N) : N 为二叉树的节点数量,BFS 需循环 N 次,占用 O(N) ;双端队列的队首和队尾的添加和删除操作的时间复杂度均为 O(1) 。
  • 空间复杂度 O(N) : 最差情况下,即当树为满二叉树时,最多有 N/2 个树节点 同时queue 中,使用 O(N)大小的额外空间。

其他优秀解答

解题思路

一般在树相关的题目中都可以考虑递归解法

代码

class Solution {
//新建一个临时列表 level ,用于存储所有层的列表
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
//当根节点为空,则返回空列表 []
if(root == null){
return new ArrayList<>(0);
}
//递归调用函数,从第0层开始
recur(root,0);
return res;
} public void recur(TreeNode root,int k){
if(root != null){
//如果列表层数小于二叉树的层数,新增当前层的列表
if(res.size() <= k){
res.add(new ArrayList<>());
}
//将当前层的元素添加到当前层列表中,层数为奇数时采用逆序
if((k & 1) == 1){
res.get(k).add(0,root.val);
}else{
res.get(k).add(root.val);
}
//递归调用二叉树的左子树,层数+1
recur(root.left,k+1);
//递归调用二叉树的右子树,层数+1
recur(root.right,k+1); }
}
}

每日一题 - 剑指 Offer 32 - III. 从上到下打印二叉树 III的更多相关文章

  1. 每日一题 - 剑指 Offer 32 - II. 从上到下打印二叉树 II

    题目信息 时间: 2019-06-25 题目链接:Leetcode tag: 队列 BFS 难易程度:简单 题目描述: 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 示 ...

  2. 每日一题 - 剑指 Offer 32 - I. 从上到下打印二叉树

    题目信息 时间: 2019-06-25 题目链接:Leetcode tag:BFS(广度优先搜索) 队列 难易程度:中等 题目描述: 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印 ...

  3. 剑指 Offer 32 - I. 从上到下打印二叉树 + 层次遍历二叉树

    剑指 Offer 32 - I. 从上到下打印二叉树 Offer_32_1 题目描述 解题思路 这题属于简单题,考察的是我们对二叉树以及层次遍历的方法. 这里只需要使用简单的队列即可完成二叉树的层次遍 ...

  4. 剑指 Offer 32 - I. 从上到下打印二叉树

    剑指 Offer 32 - I. 从上到下打印二叉树 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印. 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 ...

  5. 剑指 Offer 32 - II. 从上到下打印二叉树 II + 层次遍历二叉树 + 按层存储

    剑指 Offer 32 - II. 从上到下打印二叉树 II Offer_32 题目描述: 题解分析: 这道题我一开始想到的解决方法较粗暴,就是使用两个变量来记录当前层的节点数和下一层的结点数. 以上 ...

  6. 剑指 Offer 32 - II. 从上到下打印二叉树 II

    剑指 Offer 32 - II. 从上到下打印二叉树 II 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 例如: 给定二叉树: [3,9,20,null,null,1 ...

  7. 剑指offer 23:从上往下打印二叉树

    题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 解题思路 按照从左往右从上到下的顺序打印节点,需要我们维护一个队列,这个队列放入元素的顺序是访问队头节点(起始先放入根节点),则若当前 ...

  8. 剑指offer——33分行从上到下打印二叉树

    题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行.   题解: 使用BFS,按层打印即可 class Solution { public: vector<vector&l ...

  9. 剑指 Offer 32 - III. 从上到下打印二叉树 III

    剑指 Offer 32 - III. 从上到下打印二叉树 III 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印, ...

  10. 剑指 Offer 32 - III. 从上到下打印二叉树 III + 双端队列使用 + 蛇形打印层次遍历序列 + 正倒序输出

    剑指 Offer 32 - III. 从上到下打印二叉树 III Offer_32_3 题目详情 题解分析 本题我想的比较复杂,其实题目的要求只是需要遍历的结果逆序和正序交替,这个其实可以使用Coll ...

随机推荐

  1. Java实现 LeetCode 41 缺失的第一个正数

    41. 缺失的第一个正数 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: ...

  2. Java实现 LeetCode 14 最长公共前缀

    14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",&quo ...

  3. java实现第三届蓝桥杯方块填数

    方块填数 "数独"是当下炙手可热的智力游戏.一般认为它的起源是"拉丁方块",是大数学家欧拉于1783年发明的. 如图[1.jpg]所示:6x6的小格被分为6个部 ...

  4. HashMap(二)之面试题系列

    定义类考题 什么是Hash?什么是HashMap? HashMap 的工作原理是什么 HashMap HashTable的区别 为什么要用HashMap 源码类考题 什么是hash碰撞,怎么减少碰撞, ...

  5. Spring AOP 之二:Pointcut注解表达式

    简介 在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍 ...

  6. Spark GraphX从入门到实战

      第1章 Spark GraphX 概述 1.1 什么是 Spark GraphX   Spark GraphX 是一个分布式图处理框架,它是基于 Spark 平台提供对图计算和图挖掘简洁易用的而丰 ...

  7. CentOS7.5搭建spark2.3.1集群

    一 下载安装包 1 官方下载 官方下载地址:http://spark.apache.org/downloads.html 2  安装前提 Java8         安装成功 zookeeper  安 ...

  8. JVM进阶之路(一)

    JVM是Java程序运行的基本,了解Java程序的运行原理绝对有必要了解JVM的内容,JVM的内容其实很多,而且版本不同,其中的内容也很多不同,接下来就通过几篇文章来慢慢讲述JVM的内容. 一.Jvm ...

  9. 《Java并发编程的艺术》 第9章 Java中的线程池

    第9章 Java中的线程池 在开发过程中,合理地使用线程池能带来3个好处: 降低资源消耗.通过重复利用已创建的线程 降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要等到线程创 ...

  10. 龙芯团队完成CoreCLR MIPS64移植,在github开源

    国产龙芯的软件生态之中.NET不会缺席,毕竟 C# 与 .NetCore/Mono 也是全球几大主流的编程语言和运行平台之一,最近一段时间听到太多的鼓吹政务领域不支持.NET, 大家都明白这是某些人为 ...