LeetCode 297:二叉树的序列化与反序列化

LeetCode 297:二叉树的序列化与反序列化

LeetCode 297:二叉树的序列化与反序列化

在这里插入图片描述

一、问题背景与核心挑战

在分布式系统、数据存储和网络传输中,我们经常需要将复杂的数据结构(如二叉树)转换为可存储或传输的格式,这一过程称为序列化;而从序列化后的格式还原出原始数据结构的过程则称为反序列化

对于二叉树而言,核心挑战在于:

  1. 结构唯一性:必须完整记录树的结构,包括空节点,否则不同的树可能产生相同的序列化结果,导致反序列化时无法唯一还原。
  2. 效率平衡:在保证结构完整性的同时,兼顾序列化和反序列化的时间与空间效率。

例如,仅记录非空节点的序列 "1,2,3" 无法区分以下两棵树:

 1 1 / \ / 2 3 2 / 3 

因此,空节点的记录是实现唯一还原的关键。


二、核心思路:层序遍历(BFS)的直观实现

为了直观且高效地解决问题,我们选择**层序遍历(BFS)**作为核心方法,原因如下:

  • 层序遍历按“从上到下、从左到右”的顺序访问节点,每个节点的左右子节点位置明确,便于构建和还原。
  • 与LeetCode官方的二叉树输入格式完全一致,降低理解和调试成本。

核心思想

  • 序列化:用队列模拟层序遍历,将每个节点(包括空节点)转换为字符串,空节点用 "null" 表示,最终拼接为逗号分隔的字符串。
  • 反序列化:将字符串按逗号分割为数组,用队列模拟层序构建树,依次为每个节点分配左右子节点,空节点直接跳过。

三、序列化步骤详解

1. 初始化与队列处理

  • 若根节点为空,直接返回 "null"
  • 初始化队列,将根节点入队。
  • 初始化 StringBuilder 用于拼接结果。

2. 遍历与记录

  • 从队列中取出节点:
    • 若节点为空,向结果中添加 "null,"
    • 若节点非空,添加节点值,并将其左右子节点(无论是否为空)入队。
  • 遍历结束后,移除结果末尾多余的逗号。

示例演示(示例1)

输入树:[1,2,3,null,null,4,5]
序列化过程:

队列状态取出节点记录内容入队子节点
[1]1“1,”[2, 3]
[2, 3]2“2,”[3, null, null]
[3, null, null]3“3,”[null, null, 4, 5]
[null, null, 4, 5]null“null,”[null, 4, 5]
[null, 4, 5]null“null,”[4, 5]
[4, 5]4“4,”[5, null, null]
[5, null, null]5“5,”[null, null, null, null]

最终序列化结果:"1,2,3,null,null,4,5,null,null,null,null"


四、反序列化步骤详解

1. 初始化与数组分割

  • 若输入字符串为 "null",直接返回 null
  • 将字符串按逗号分割为数组,得到所有节点的字符串表示。

2. 队列构建树

  • 第一个元素为根节点的值,创建根节点并入队。
  • 初始化索引 i=1,遍历队列:
    • 取出队首节点作为父节点。
    • 处理左子节点:若数组 i 位置不是 "null",创建左子节点并入队,i++
    • 处理右子节点:若数组 i 位置不是 "null",创建右子节点并入队,i++
  • 遍历结束后,返回根节点。

示例演示(示例1)

输入字符串:"1,2,3,null,null,4,5,null,null,null,null"
分割数组:["1","2","3","null","null","4","5","null","null","null","null"]
反序列化过程:

队列状态父节点左子节点右子节点索引i
[1]1233
[2, 3]2nullnull5
[3]3457
[4, 5]4nullnull9
[5]5nullnull11

最终还原的树结构与输入完全一致。


五、完整代码实现(Java)

importjava.util.LinkedList;importjava.util.Queue;/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */publicclassCodec{// Encodes a tree to a single string.publicStringserialize(TreeNode root){if(root ==null){return"null";}Queue<TreeNode> queue =newLinkedList<>(); queue.offer(root);StringBuilder sb =newStringBuilder();while(!queue.isEmpty()){TreeNode node = queue.poll();if(node ==null){ sb.append("null,");}else{ sb.append(node.val).append(","); queue.offer(node.left); queue.offer(node.right);}}// 移除末尾多余的逗号if(sb.length()>0){ sb.setLength(sb.length()-1);}return sb.toString();}// Decodes your encoded data to tree.publicTreeNodedeserialize(String data){if(data ==null|| data.equals("null")){returnnull;}String[] parts = data.split(",");Queue<TreeNode> queue =newLinkedList<>();TreeNode root =newTreeNode(Integer.parseInt(parts[0])); queue.offer(root);int i =1;while(!queue.isEmpty()&& i < parts.length){TreeNode parent = queue.poll();// 处理左子节点if(!parts[i].equals("null")){TreeNode left =newTreeNode(Integer.parseInt(parts[i])); parent.left = left; queue.offer(left);} i++;// 处理右子节点if(i < parts.length &&!parts[i].equals("null")){TreeNode right =newTreeNode(Integer.parseInt(parts[i])); parent.right = right; queue.offer(right);} i++;}return root;}}// Your Codec object will be instantiated and called as such:// Codec ser = new Codec();// Codec deser = new Codec();// TreeNode ans = deser.deserialize(ser.serialize(root));

六、思路延申:前序遍历的递归实现

除了层序遍历,前序遍历(DFS) 也是一种常见的序列化方式,其核心是“根-左-右”的递归顺序,空节点同样用 "null" 表示。

前序序列化

publicStringserializePre(TreeNode root){if(root ==null){return"null";}return root.val +","+serializePre(root.left)+","+serializePre(root.right);}

前序反序列化

importjava.util.Arrays;importjava.util.LinkedList;importjava.util.Queue;publicTreeNodedeserializePre(String data){Queue<String> queue =newLinkedList<>(Arrays.asList(data.split(",")));returnbuildTree(queue);}privateTreeNodebuildTree(Queue<String> queue){String val = queue.poll();if(val.equals("null")){returnnull;}TreeNode node =newTreeNode(Integer.parseInt(val)); node.left =buildTree(queue); node.right =buildTree(queue);return node;}

两种方法的对比

方法优点缺点
层序遍历直观易懂,与LeetCode输入格式一致,非递归实现,避免栈溢出序列化字符串较长,包含较多空节点记录
前序遍历代码简洁,递归结构清晰,适合理解树的递归性质大数据流下可能栈溢出(递归深度限制)

七、复杂度分析

  • 时间复杂度:序列化和反序列化均为 (O(n)),每个节点仅处理一次,队列操作均摊为 (O(1))。
  • 空间复杂度:序列化和反序列化均为 (O(n)),队列最多存储 (n) 个节点(最坏情况为完全二叉树的最后一层)。

八、总结与应用场景

二叉树的序列化与反序列化是数据结构与算法中的经典问题,其核心在于完整记录结构信息,确保唯一还原。在实际应用中:

  • 层序遍历适合大数据流和分布式场景,非递归实现避免了栈溢出风险。
  • 前序遍历适合算法题和教学场景,递归结构清晰,便于理解树的性质。

无论选择哪种方法,只要保证空节点的记录和遍历顺序的一致性,就能实现高效且可靠的序列化与反序列化。

Read more

2026年1月远程工具横评:UU远程以全能六边形战士之姿,重塑行业性能标杆

2026年1月远程工具横评:UU远程以全能六边形战士之姿,重塑行业性能标杆

目录 写在前面:一场关于“效率”的军备竞赛 一、 核心突破:详解UU远程2026年1月重磅升级,如何解决远程协助世纪难题? 1.1 自定义验证码:把“报号码”从技术活变成家常便饭 1.2 客户端安全锁:远程协助时的“定海神针” 1.3 免登录远程协助:打破第一道门槛,实现真正“零门槛” 1.4 UU远程运维版定向开放:命令行批量管控,专为专业场景打造的效率引擎 二、 硬核横评:六大远程软件谁是2026年1月的性能之王? 2.1 性能之王:画质与延迟的终极较量 2.2 功能六边形战士:谁才是真正的全能王? 2.3 价格与限制:免费还是套路? 三、 综合评分与总结:2026年1月,你的最佳选择是谁?

By Ne0inhk
【Python 量化入门】AKshare 保姆级使用教程:零成本获取股票 / 基金 / 期货全市场金融数据

【Python 量化入门】AKshare 保姆级使用教程:零成本获取股票 / 基金 / 期货全市场金融数据

做量化交易、财经数据分析、投资复盘的开发者和投资者,经常会遇到核心痛点:付费金融数据接口成本高、免费 API 注册流程繁琐、多市场数据分散难以整合。告别 QMT 回测烦恼!手把手教你搭建 MiniQMT+Backtrader 量化回测框架 本文就给大家详细讲解 Python 量化圈的开源神器AKshare,从安装到核心功能实战全覆盖,代码可直接复制运行,零基础也能一键获取全市场金融行情数据。 一、AKshare 是什么? AKshare 是一款基于 Python 开发的开源金融数据接口库,专为个人投资者、量化爱好者、财经数据分析人员打造,是目前国内生态最完善、维护最活跃的免费金融数据工具之一。 它支持股票、期货、基金、外汇、债券、指数、加密货币等多种主流金融市场的数据获取,核心优势如下: * 免费开源:完全开源免费,无隐藏收费,个人非商用零成本使用,无需开通付费会员 * 数据覆盖全面:A 股、

By Ne0inhk
python101-高校学生宿舍报修系统vue3

python101-高校学生宿舍报修系统vue3

目录 * 系统概述 * 核心功能模块 * 技术实现要点 * 扩展性与优化方向 * 开发技术路线 * 相关技术介绍 * 核心代码参考示例 * 结论 * 源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式! 系统概述 Python101-高校学生宿舍报修系统基于Vue3前端框架开发,专为高校宿舍管理场景设计,实现学生在线提交报修请求、管理员处理工单、状态跟踪等功能。系统采用前后端分离架构,后端通常搭配Python(如Django或Flask)提供API支持。 核心功能模块 学生端功能 * 报修申请:填写故障类型、位置、描述并上传图片。 * 工单查询:实时查看报修进度(待处理/处理中/已完成)。 * 评价反馈:对已完成的维修服务进行评分或留言。 管理员端功能 * 工单分配:将报修任务指派给维修人员。 * 进度更新:修改工单状态并通知学生。 * 数据统计:分析故障高频类型及维修效率。 技术实现要点 * 前端技术栈:Vue3 + TypeScript + Element Plus/Pinia(

By Ne0inhk
AI 的智能体专栏:手把手教你用豆包打造专属 Python 智能管家,轻松解决编程难题

AI 的智能体专栏:手把手教你用豆包打造专属 Python 智能管家,轻松解决编程难题

AI 的智能体专栏:手把手教你用豆包打造专属 Python 智能管家,轻松解决编程难题 AI 的智能体专栏:手把手教你用豆包打造专属 Python 智能管家,轻松解决编程难题,本文介绍了如何利用豆包平台打造专属Python智能管家。首先简述豆包平台的核心优势,接着说明创建前的准备工作,包括注册账号、明确定位和收集训练资料。随后详细讲解创建流程,从新建智能体、基础设置、能力配置到测试优化,还提及集成代码执行环境等高级功能扩展,以及使用技巧与实际应用案例。该智能官能解决多种Python编程问题,可提升学习效率和问题解决速度,是实用的个性化编程助手。 前言     人工智能学习合集专栏是 AI 学习者的实用工具。它像一个全面的 AI 知识库,把提示词设计、AI 创作、智能绘图等多个细分领域的知识整合起来。无论你是刚接触 AI 的新手,还是有一定基础想提升的人,都能在这里找到合适的内容。从最基础的工具操作方法,到背后深层的技术原理,专栏都有讲解,还搭配了实例教程和实战案例。这些内容能帮助学习者一步步搭建完整的 AI 知识体系,让大家快速从入门进步到精通,

By Ne0inhk