LeetCode 第 297 题「二叉树的序列化与反序列化」
字数 963 2025-10-26 05:47:38
我来给你讲解 LeetCode 第 297 题「二叉树的序列化与反序列化」。
题目描述
设计一个算法,将二叉树序列化为一个字符串,并且可以将字符串反序列化为原始的二叉树结构。不限制你的序列化/反序列化算法执行逻辑,只需要保证二叉树可以序列化为字符串,并且字符串可以反序列化为原始的树结构。
解题思路
第一步:理解问题本质
序列化就是将二叉树结构转换为字符串表示,反序列化就是将字符串还原为二叉树。关键是要选择一种遍历方式,既能完整保存树的结构信息,又能方便地重建。
第二步:选择遍历方式
常用的二叉树遍历方式有:
- 前序遍历:根 → 左 → 右
- 中序遍历:左 → 根 → 右
- 后序遍历:左 → 右 → 根
- 层序遍历:按层次遍历
前序遍历是最直观的选择,因为序列化时第一个元素就是根节点,便于反序列化时重建。
第三步:处理空节点
为了能够准确重建树的结构,我们需要标记空节点。通常用特殊字符如:
"null"或"#"表示空节点- 用分隔符如
","分隔各个节点值
第四步:序列化过程(前序遍历)
- 从根节点开始递归遍历
- 如果当前节点为空,在字符串中添加
"null" - 如果当前节点不为空,添加节点值
- 继续递归处理左子树和右子树
示例:
1
/ \
2 3
/ \
4 5
序列化结果:"1,2,null,null,3,4,null,null,5,null,null"
第五步:反序列化过程
- 将序列化字符串按分隔符拆分成节点值列表
- 从列表开头开始处理(前序遍历顺序)
- 如果遇到
"null",返回空节点 - 否则用当前值创建节点,递归构建左子树和右子树
第六步:代码实现细节
序列化步骤:
def serialize(root):
def preorder(node):
if not node:
result.append("null")
return
result.append(str(node.val))
preorder(node.left)
preorder(node.right)
result = []
preorder(root)
return ",".join(result)
反序列化步骤:
def deserialize(data):
def build():
if not values:
return None
val = values.pop(0)
if val == "null":
return None
node = TreeNode(int(val))
node.left = build()
node.right = build()
return node
values = data.split(",")
return build()
第七步:复杂度分析
- 时间复杂度:O(n),每个节点访问一次
- 空间复杂度:O(n),递归栈空间和存储序列化字符串的空间
第八步:其他实现方式
除了前序遍历,还可以使用:
- 层序遍历:更适合人类阅读,但实现稍复杂
- JSON格式:直接利用语言特性,但可能不符合题目要求
第九步:关键要点总结
- 必须标记空节点:否则无法确定树的确切结构
- 前序遍历最直观:根节点在开头,便于重建
- 分隔符很重要:确保能正确解析各个值
- 递归思想:序列化和反序列化都适合用递归实现
这种方法可以处理任意形状的二叉树,包括退化成链表的特殊情况。