【LeetCode】297.二叉树的序列化与反序列化(手绘图解,BFS+DFS两种方法)

本文介绍了LeetCode第297题——二叉树的序列化与反序列化。详细解析了使用DFS(递归)和BFS两种方法实现。DFS方法中,序列化采用前序遍历,反序列化同样使用递归。BFS方法序列化和反序列化都基于广度优先搜索,通过队列操作完成。文章提供了完整代码实现。
摘要由CSDN通过智能技术生成

题目

链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

问题描述:image-20200620134118967

解析

方法1:DFS(递归)

递归可以理解为:转交职责
  • 递归一棵树,只关注当前的单个节点就好
  • 剩下的工作,交给递归完成
    • “serialize 函数,你能不能帮我序列化我的左右子树?我等你的返回结果,再追加到我身上。”
  • 为什么选择 前序遍历,因为在反序列化时,根|左|右,更容易定位根节点值
  • 遇到 null 节点也要翻译成一个特殊符号,反序列化时才知道这里对应 null 节点

image.png

序列化 代码
const serialize = (root) => {
   
  if (root == null) return 'X,' // 遇到null节点
  const leftSerialized = serialize(root.left)   //左子树的序列化字符串
  const rightSerialized = serialize(root.right) //右子树的序列化字符串
  return root.val + ',' + leftSerialized + rightSerialized // 根|左|右
}

反序列化——也是递归

序列化时是前序遍历,所以序列化字符串呈现这样的排列:
“根|(根|(根|左|右)|(根|左|右))|(根|(根|左|右)|(根|左|右))”

image.png

构建树的函数 buildTree
  • buildTree 接收的 “状态” 是 list 数组,由序列化字符串转成
  • 按照前序遍历的顺序:先构建根节点,再构建左子树,再构建右子树
  • list 数组首项是 当前子树的根节点,弹出,先构建它
buildTree 关注当前节点,然后职责转交
  • 将 list 数组的首项弹出,考察它
  • 如果它为 ‘X’ ,直接返回 null ,没有子树可构建
  • 如果它不为 ‘X’,则为它创建 node 节点,并构建子树
  • 递归调用 buildTree 构建左子树
  • 递归调用 buildTree 构建右子树
  • 以 node 为根节点的子树,构建完毕,向上返回

image.png

反序列化 代码
const buildTree = (list) => {
           // dfs函数
  const nodeVal = list.shift()       // 当前考察的节点
  if (nodeVal == 'X') return null    // 是X,返回null给父调用
  const node = new TreeNode(nodeVal) // 创建node节点
  node.left = buildTree(list)        // 构建node的左子树
  node.right = buildTree(list)       // 构建node的右子树
  return node                        // 返回以node为根节点的子树给父调用
}
const deserialize = (data) => {
   
  const list = data.split(',')       // 转成list数组
  return buildTree(list)             // 构建树,dfs的入口
}

完整实现:

实现1:耗时比较大

public class Codec {
   
    public String rserialize(TreeNode root, String str) {
   
        if (root == null) {
   
            str += "None,";
        } else {
   
            str += str.valueOf(root.val) + ",";
            str = rserialize(root.left, str);
            str = rserialize(root.right, str);
        }
        return str;
    }
  
    public String serialize(TreeNode root) {
   
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值