剑指 Offer 32 - III. 从上到下打印二叉树 III
时间:2021-09-04
本文章向大家介绍剑指 Offer 32 - III. 从上到下打印二叉树 III,主要包括剑指 Offer 32 - III. 从上到下打印二叉树 III使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
剑指 Offer 32 - III. 从上到下打印二叉树 III
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7],
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
提示:
- 节点总数 <= 1000
一、层序遍历 + 双端队列
做题思路:与剑指 Offer 32 - I. 从上到下打印二叉树 - RainsX - 博客园 (cnblogs.com)和剑指 Offer 32 - II. 从上到下打印二叉树 II - RainsX - 博客园 (cnblogs.com)类似,只是在BFS循环的时候加入了判断奇偶数的判定。当res.size()为偶数的时候,添加node.val的头部,否则为尾部。
而且这道题可以与剑指 Offer 32 - I. 从上到下打印二叉树 - RainsX - 博客园 (cnblogs.com)、剑指 Offer 32 - II. 从上到下打印二叉树 II - RainsX - 博客园 (cnblogs.com)一起连着做,然后加深对BFS和输的理解。
个人建议,可以试着把这个代码部分模块当做模板来熟悉,因为后续可能也有同样的算法题需要此类模板。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> deque = new LinkedList<>();
List<List<Integer>> res = new ArrayList<List<Integer>>();
if(root != null) deque.add(root);
while(!deque.isEmpty()) {
LinkedList<Integer> tmp = new LinkedList<>();
for (int i = deque.size(); i>0; i--) {
TreeNode node = deque.poll();
if (res.size() % 2 == 0) tmp.addLast(node.val);
else tmp.addFirst(node.val);
if (node.left != null) deque.add(node.left);
if (node.right != null) deque.add(node.right);
}
res.add(tmp);
}
return res;
}
}
二、层序遍历 + 双端队列(奇偶层逻辑分离)
这个做题思路是K神的思路,比起一开始简化了很多步骤,这个梗容易看懂一些。
算法流程如下:
BFS循环:
- 循环打印奇数/偶数层,当deque为空时候跳出
- 打印奇数层的时候,依次从左到右
- 打印偶数层的时候,依次从右到左
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) deque.add(root);
while(!deque.isEmpty()) {
// 打印奇数层
List<Integer> tmp = new ArrayList<>();
for(int i = deque.size(); i > 0; i--) {
// 从左向右打印
TreeNode node = deque.removeFirst();
tmp.add(node.val);
// 先左后右加入下层节点
if(node.left != null) deque.addLast(node.left);
if(node.right != null) deque.addLast(node.right);
}
res.add(tmp);
if(deque.isEmpty()) break; // 若为空则提前跳出
// 打印偶数层
tmp = new ArrayList<>();
for(int i = deque.size(); i > 0; i--) {
// 从右向左打印
TreeNode node = deque.removeLast();
tmp.add(node.val);
// 先右后左加入下层节点
if(node.right != null) deque.addFirst(node.right);
if(node.left != null) deque.addFirst(node.left);
}
res.add(tmp);
}
return res;
}
}
三、层序遍历 + 倒序
这个倒序的思路,其实只要懂了判断奇数/偶数层,就更容易什么时候倒序。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if (root != null) queue.add(root);
while (!queue.isEmpty()) {
List<Integer> tmp = new ArrayList<>();
for (int i = queue.size(); i > 0; i--) {
TreeNode node = queue.poll();
tmp.add(node.val);
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
//当偶数层的时候就倒序,就跟方法一一样改变顺序即可
if (res.size() % 2 != 0) Collections.reverse(tmp);
res.add(tmp);
}
return res;
}
}
参考链接:
原文地址:https://www.cnblogs.com/RainsX/p/15227660.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【go】剑指offer:用26个英文字母组合表示列数
- Flink——运行在数据流上的有状态计算框架和处理引擎
- goland破解教程
- HTTP接口设计
- NSQ分布式消息基础入门
- 【golang】剑指offer 最大n位数
- Spark提交Jar任务警告: Initial job has not accepted any resources;
- Defer,Panic,and Recover
- Spark——底层操作RDD,基于内存处理数据的计算引擎
- Go 项目最佳实践
- 虚拟机更换JDK版本步骤(Hadoop集群)
- JavaSE重点复习
- [数据结构与算法] 树结构之二叉排序树、平衡二叉树、多路查找树
- 工作后, 你一定不能错过技术之JDK1.8的新特性
- 【Go】剑指offer:二叉树子树的判断