LeetCode 第 297 题「二叉树的序列化与反序列化」
字数 963 2025-10-26 05:47:38

我来给你讲解 LeetCode 第 297 题「二叉树的序列化与反序列化」

题目描述

设计一个算法,将二叉树序列化为一个字符串,并且可以将字符串反序列化为原始的二叉树结构。不限制你的序列化/反序列化算法执行逻辑,只需要保证二叉树可以序列化为字符串,并且字符串可以反序列化为原始的树结构。

解题思路

第一步:理解问题本质

序列化就是将二叉树结构转换为字符串表示,反序列化就是将字符串还原为二叉树。关键是要选择一种遍历方式,既能完整保存树的结构信息,又能方便地重建。

第二步:选择遍历方式

常用的二叉树遍历方式有:

  • 前序遍历:根 → 左 → 右
  • 中序遍历:左 → 根 → 右
  • 后序遍历:左 → 右 → 根
  • 层序遍历:按层次遍历

前序遍历是最直观的选择,因为序列化时第一个元素就是根节点,便于反序列化时重建。

第三步:处理空节点

为了能够准确重建树的结构,我们需要标记空节点。通常用特殊字符如:

  • "null""#" 表示空节点
  • 用分隔符如 "," 分隔各个节点值

第四步:序列化过程(前序遍历)

  1. 从根节点开始递归遍历
  2. 如果当前节点为空,在字符串中添加 "null"
  3. 如果当前节点不为空,添加节点值
  4. 继续递归处理左子树和右子树

示例

    1
   / \
  2   3
     / \
    4   5

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

第五步:反序列化过程

  1. 将序列化字符串按分隔符拆分成节点值列表
  2. 从列表开头开始处理(前序遍历顺序)
  3. 如果遇到 "null",返回空节点
  4. 否则用当前值创建节点,递归构建左子树和右子树

第六步:代码实现细节

序列化步骤

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格式:直接利用语言特性,但可能不符合题目要求

第九步:关键要点总结

  1. 必须标记空节点:否则无法确定树的确切结构
  2. 前序遍历最直观:根节点在开头,便于重建
  3. 分隔符很重要:确保能正确解析各个值
  4. 递归思想:序列化和反序列化都适合用递归实现

这种方法可以处理任意形状的二叉树,包括退化成链表的特殊情况。

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