题目描述
思路解析动画文字版
下面 9 步动画会按主解代码推进,而不是泛泛讲题型。
序列化目标 · 编码成可还原的字符串:序列化就是把树变成一个字符串、之后还能一模一样还原。关键技巧:用前序遍历,并且把空节点也记成 #——这样结构才不会丢。
序列化 · 前序输出值,空孩子补 #:从根 1 开始前序走:输出 1,进左子树输出 2;2 是叶子、左右都空,于是补两个 #。串现在是 1,2,#,#。
序列化 · 走完右子树:回到根、进右子树,依次输出 3、4、5,每个叶子的空孩子都补 #。整棵树的序列就是:1,2,#,#,3,4,#,#,5,#,#。
为什么必须记空节点 #:如果不记空节点,光一串 1,2,3,4,5 没法区分树的结构——同一串能对应多棵不同的树。记上 #,每个节点的孩子是空还是子树就都标清了,才能唯一还原。
反序列化 · 按前序顺序消费:反序列化反着来:按前序顺序一个个读。读到值就建节点、再递归去建它的左右;读到 # 就返回空(递归出口)。消费顺序和当初序列化完全一致。
还原完成 · 和原树一模一样:按同样的前序顺序把整串消费完,每个 # 对应一个空、每个值对应一个节点——原树被完整重建。序列化与反序列化是一对互逆操作。
记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
迁移阶梯:把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
边界三连:二叉树的序列化与反序列化 的边界先看最小规模、空输入和会触发特殊分支的极端样例。
面试追问:二叉树的序列化与反序列化 的追问重点,是把动画里的状态定义、边界和复杂度讲成自己的话。
参考代码
class Codec: def serialize(self, root): vals = [] def dfs(node): if not node: vals.append('#') return vals.append(str(node.val)) dfs(node.left) dfs(node.right) dfs(root) return ','.join(vals) def deserialize(self, data): vals = iter(data.split(',')) def dfs(): val = next(vals) if val == '#': return None node = TreeNode(int(val)) node.left = dfs() node.right = dfs() return node return dfs()复杂度
- 时间复杂度:O(n),每个节点和空指针处理一次
- 空间复杂度:O(n),序列和递归栈
易错点
面试追问把动画讲成自己的话
追问为什么前序遍历适合做序列化?
追问不标记空节点行不行?
追问层序(BFS)也能序列化吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最近公共祖先
LeetCode 236 · 中等 · 沿着 树 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题