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

剑指offer-59、按之字形顺序打印⼆叉树

题⽬描述

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

示例1
输⼊:{8,6,10,5,7,9,11}
返回值:[[8],[10,6],[5,7,9,11]]

思路及解答

双向链表(推荐)

  1. 借助双向链表,初始化⼀个添加⽅向 boolean 值,先将根节点添加进去:
  2. 获取 list ⾥⾯剩下的元素的个数,挨个取出就是⼀层,取出的时候,如果 reverse 为 true ,则往链表的第 0 个索引位置添加,否则直接在后⾯添加,然后判断每⼀个取出来的节点的左右节点是不是为空,不为空则加⼊链表。
  3. 每⼀层处理完之后,将 list 加⼊结果集中,然后翻转 reverse 的值,继续判断 list 是不是为空,执⾏第⼆步循环。
public class Solution {public ArrayList < ArrayList < Integer >> Print(TreeNode pRoot) {LinkedList < TreeNode > nodes = new LinkedList < > ();ArrayList < ArrayList < Integer >> results = new ArrayList();boolean reverse = true;if (pRoot != null) {nodes.add(pRoot);while (!nodes.isEmpty()) {ArrayList < Integer > integers = new ArrayList();int size = nodes.size();for (int i = 0; i < size; i++) {TreeNode node = nodes.poll();if (reverse) {integers.add(node.val);} else {integers.add(0, node.val);}if (node.left != null) {nodes.offer(node.left);}if (node.right != null) {nodes.offer(node.right);}}if (integers.size() != 0) {results.add(integers);}reverse = !reverse;}}return results;}
}
  • 空间复杂度由于借助了额外的 list ,为 O(n)
  • 时间复杂度,由于每个节点进⼊队列⼜出来,为 O(2n) ,也是 O(n) 。

队列 + 方向反转

这是最直接的方法。我们进行标准的层序遍历,但用一个标志位记录当前层是奇数层还是偶数层。对于偶数层,我们在将该层的节点值列表加入最终结果前,先进行反转

import java.util.*;public class Solution {public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();if (pRoot == null) return result;Queue<TreeNode> queue = new LinkedList<>();queue.offer(pRoot);boolean leftToRight = true; // 方向标志,true表示从左到右while (!queue.isEmpty()) {int levelSize = queue.size(); // 当前层的节点数ArrayList<Integer> levelList = new ArrayList<>();// 遍历当前层的所有节点for (int i = 0; i < levelSize; i++) {TreeNode node = queue.poll();levelList.add(node.val); // 将节点值加入当前层列表// 将下一层的节点按标准顺序(先左后右)加入队列if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}// 如果是偶数层(从第0层开始算则为奇数索引),反转当前层列表if (!leftToRight) {Collections.reverse(levelList);}result.add(levelList);leftToRight = !leftToRight; // 切换方向}return result;}
}
  • 时间复杂度:O(n)。每个节点被访问一次,对于偶数层,Collections.reverse的时间复杂度为 O(当前层节点数),所有层的节点数相加为 n,因此总时间复杂度为 O(n)。
  • 空间复杂度:O(n)。队列和结果列表所需空间与节点数 n 成线性关系。

双栈交替

利用栈后进先出(LIFO)的特性来自然地实现顺序的反转。我们使用两个栈,一个用于处理当前层,另一个用于存储下一层的节点

import java.util.*;public class Solution {public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {ArrayList<ArrayList<Integer>> result = new ArrayList<>();if (pRoot == null) return result;Stack<TreeNode> stack1 = new Stack<>(); // 处理奇数层(从左到右)Stack<TreeNode> stack2 = new Stack<>(); // 处理偶数层(从右到左)stack1.push(pRoot);// 当两个栈都为空时,遍历结束while (!stack1.isEmpty() || !stack2.isEmpty()) {ArrayList<Integer> levelList = new ArrayList<>();if (!stack1.isEmpty()) {// 处理stack1(奇数层),其子节点将以“从右到左”的顺序压入stack2while (!stack1.isEmpty()) {TreeNode node = stack1.pop();levelList.add(node.val);// 关键:先左子节点后右子节点入栈,出栈顺序则为先右后左if (node.left != null) stack2.push(node.left);if (node.right != null) stack2.push(node.right);}} else {// 处理stack2(偶数层),其子节点将以“从左到右”的顺序压入stack1while (!stack2.isEmpty()) {TreeNode node = stack2.pop();levelList.add(node.val);// 关键:先右子节点后左子节点入栈,出栈顺序则为先左后右if (node.right != null) stack1.push(node.right);if (node.left != null) stack1.push(node.left);}}result.add(levelList);}return result;}
}
  • 时间复杂度:O(n)。每个节点被压入栈和弹出栈各一次。
  • 空间复杂度:O(n)。两个栈在最坏情况下共同存储 n 个节点。
http://www.jsqmd.com/news/203981/

相关文章:

  • ComfyUI安全限制终极解决方案:快速解除操作限制
  • 云南省曲靖市自建房设计公司评测排行榜:6 家主流企业实地测评,哪家更靠谱? - 苏木2025
  • 贵州省凯里市自建房设计公司哪家强?2026年最新权威靠谱测评榜单抢先看 - 苏木2025
  • Golang + 云原生智能体工作流
  • 谁是TOP1?云南省普洱市自建房设计公司评测排行榜 + 真实建房案例参考 - 苏木2025
  • Proteus仿真在PCB设计前的电路功能验证完整指南
  • 2026年工艺好的门窗品牌推荐:龙头复合门窗品牌有哪些? - 工业品牌热点
  • 云南省玉溪市自建房设计公司排行榜出炉!权威评测 + 真实案例,建房选对不踩坑 - 苏木2025
  • 想在贵州省都匀市农村盖房子,靠谱的自建房设计公司口碑推荐 - 苏木2025
  • PHP程序员 MSP(最小可存活问题)的庖丁解牛
  • 云南省保山市自建房设计公司哪家强?2025最新评测排行榜 + 5 星企业推荐 - 苏木2025
  • Undetectable接入亮数据代理IP深度测评:高效、稳定、适配性极强的海外多账号运营利器
  • 知乎专栏发文策略:以深度测评建立专业权威形象
  • 密集型语言模型是什么?解读VibeThinker-1.5B架构特点
  • 为什么说VibeThinker不是聊天机器人?明确其推理定位避免误用
  • 集成到CI/CD流水线:自动审查Pull Request中的代码逻辑缺陷
  • 微博开源项目亮点:VibeThinker-1.5B对中文社区的技术贡献
  • 【高级前端必修课】:Dify环境下Next.js全局错误处理的最佳实践
  • 图解说明COB封装中高端LED灯珠品牌光效差异
  • LiveCodeBench v5/v6双高分:代码生成能力的真实体现
  • 为什么你的Dify日志总是漏关键信息?1.11.1版本日志配置避雷指南
  • 使用Xilinx FPGA实现SR触发器:新手入门必看
  • ViGEmBus虚拟控制器驱动完整指南:从零基础到精通掌握
  • ViGEmBus虚拟控制器驱动:让任何设备变身专业游戏手柄
  • CSDN官网技术文章太多?用VibeThinker快速提取核心算法思路
  • 输入法词库自由迁移:深蓝转换工具快速上手完整指南
  • E-Hentai智能下载工具:高效批量获取方案全解析
  • hbuilderx制作网页打造个性化学习门户核心要点
  • vivado固化程序烧写步骤实战案例(Zynq-7000)
  • 算法思维训练新模式:将VibeThinker嵌入你的每日编程打卡流程