【LeetCode】297. 二叉树的序列化与反序列化

news2024/12/24 2:25:58

1.问题

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

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

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例 1

在这里插入图片描述

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

示例 2

输入:root = []
输出:[]

示例 3

输入:root = [1]
输出:[1]

示例 4

输入:root = [1,2]
输出:[1,2]

提示

  • 树中结点数在范围 [0, 104] 内
  • -1000 <= Node.val <= 1000

2.解题思路

二叉树有很多种遍历思路,如要解决本题,可以参考以下二叉树的遍历算法,序列化不用多说,反序列化就是逆向思考之前是怎么序列化的。本章主要讲解怎么利用层序遍历的思想解决反序列化问题。

二叉树遍历系列

  • 144.二叉树的前序遍历
  • 94.二叉树的中序遍历
  • 145.二叉树的后续遍历
  • 102.二叉树的层序遍历
  • 107.二叉树的层序遍历II
  • 103.二叉树的锯齿形层序遍历(之字形遍历)
  • 199.二叉树的右视图

2.1 BFS

在102.二叉树的层序遍历一文中,我们利用队列的性质对二叉树进行了层序遍历,本章,在序列化时我们也可以用队列,只是不需要分层标识,比如我们可以把它看成是这样:
在这里插入图片描述
我们定义一个空节点,用以标识某个节点无左或右子节点。用下划线分割各个节点的值。

int INF = -2000;
TreeNode emptyNode = new TreeNode(INF);

则序列化后的结果为:1_2_3_-2000_-2000_4_5_-2000_-2000_-2000_-2000;
反序列化时,利用队列,弹出头结点,包装成二叉树节点,对于序列化的序列,取出两个节点,只要值不是-2000,就可以将父子节点进行关联,再入队,依次循环。

2.2 递归

这里以前序遍历思想为例,其他中序、后序遍历类似。
同样,利用上述2.1节中的自定义空节点标识二叉树的空子节点。序列化伪代码大致如下:

String serialize(TreeNode root){
	if (root == null) {
		return INF;
	}
	//左节点
	String left=serialize(root.left);
	//右节点
	String right=serialize(root.right);
	return root.val+"_"+left.val+"_"+right.val;
}

反序列化

TreeNode deserialize(String str){
	//分离节点值
	ss=str.split("_");
	//递归反序列化
	return buildTree(ss);
}

TreeNode buildTree(ss){
	//弹出第一个value
	value=ss.poll();
	//非自定义空节点 递归
	if(value==INF){
		return null;
	}
	//构造节点
	TreeNode root=new TreeNode(value);
	root.left=buildTree(ss);
	root.right=buildTree(ss);
	return root;
}


3.代码

import java.util.ArrayDeque;
import java.util.Deque;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
	//定义空节点的值
    int INF = -2000;
    TreeNode emptyNode = new TreeNode(INF);

	//BFS
    String Serialize(TreeNode root) {
        if (root == null) {
        	return "";
        }
		//序列化的临时结果
        StringBuilder sb = new StringBuilder();
        Deque<TreeNode> d = new ArrayDeque<>();
        d.addLast(root);
        while (!d.isEmpty()) {
        	//弹出一个节点,第一个是root
            TreeNode poll = d.pollFirst();
            //序列化的值以下划线分割
            sb.append(poll.val + "_");
            //非自定义的空节点关联父节点
            if (!poll.equals(emptyNode)) {
                d.addLast(poll.left != null ? poll.left : emptyNode);
                d.addLast(poll.right != null ? poll.right : emptyNode);
            }
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

    //BFS
    TreeNode Deserialize(String data) {
        if (data.equals("")) {
        	return null;
        }

        String[] ss = data.split("_");
        int n = ss.length;
        //根节点
        TreeNode root = new TreeNode(Integer.parseInt(ss[0]));
        Deque<TreeNode> d = new ArrayDeque<>();
        d.addLast(root);
        for (int i = 1; i < n - 1; i += 2) {
            TreeNode poll = d.pollFirst();
            int a = Integer.parseInt(ss[i]);
            int b = Integer.parseInt(ss[i + 1]);
            //非自定义空节点的值,包装成二叉树的节点,关联上父节点
            if (a != INF) {
                poll.left = new TreeNode(a);
                d.addLast(poll.left);
            }
            if (b != INF) {
                poll.right = new TreeNode(b);
                d.addLast(poll.right);
            }
        }
        return root;
    }

	//递归序列化和反序列化
	//前序遍历
    String Serialize2(TreeNode root) {
        if (null == root) {
            return String.valueOf(INF);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(root.val)
        .append("_")
        .append(Serialize(root.left))
        .append("_")
        .append(Serialize(root.right));
        
        return sb.toString();
    }

    TreeNode Deserialize2(String str) {
        if (null == str || "".equals(str)) {
            return null;
        }
        //将节点元素值分离
        String[] s = str.split("_");
        List<String> list = Arrays.stream(s).collect(Collectors.toList());
        TreeNode root = buildTree(list);
        return root;
    }

    private TreeNode buildTree(List<String> list) {
        int rootValue = Integer.parseInt(list.remove(0));
        if ( rootValue == INF) {
            return null;
        }
        TreeNode root = new TreeNode(rootValue);
        root.left = buildTree(list);
        root.right = buildTree(list);
        return root;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/464231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Css如何优雅的实现抽奖转盘

如图&#xff0c;抽奖转盘&#xff0c;可以拆分为几部分&#xff1a; 1.底部大圆&#xff1b; 2.中间小圆&#xff1b; 3.扇形区&#xff1b; 4.扇形内部奖品区&#xff1b; 5.抽奖按钮&#xff1b; 6.点击抽奖按钮时旋转动效及逻辑&#xff1b; 这其中&#xff0c;扇形区&am…

集成灶/小家电语音提示芯片方案-WTN6040-8S唯创知音自主研发

集成灶一直是厨房中常用设备之一&#xff0c;而现代技术的不断发展&#xff0c;为集成灶的升级提供了更多的可能性。深圳唯创知音为了让家用电器更加便民&#xff0c;专门为集成灶开发了一款语音IC方案——WTN6040语音芯片方案&#xff0c;这款芯片可以满足集成灶对语音提示功能…

独家专访丨TheStage.ai :当 AI 邂逅 Web3

随着2022年末ChatGPT走红&#xff0c;AI再次成为人们关注的焦点。上一次AI掀起舆论热潮&#xff0c;还是2016年AlphaGo以4:1战胜世界顶级围棋棋手李世石。 但与上次不同的是&#xff0c;这次AI更强大了。在接受强化训练后&#xff0c;AI可以对用户的需求创造新内容。 面对AI的快…

关于API数据接口的使用说明

API&#xff08;Application Programming Interface&#xff09;是一种让不同软件之间进行数据交换和通信的技术&#xff0c;使用API可以减少开发者的工作量&#xff0c;提高软件应用的效率和可靠性。本文将介绍API数据接口的使用方式和注意事项。 使用API数据接口的方式&…

Python一行代码实现文件共享【内网穿透公网访问】

目录 1. 前言 2. 视频教程 3. 本地文件服务器搭建 3.1 python的安装和设置 3.2 cpolar的安装和注册 4. 本地文件服务器的发布 4.1 Cpolar云端设置 4.2 Cpolar本地设置 5. 公网访问测试 6. 结语 转载自内网穿透工具的文章&#xff1a;Python一行代码实现文件共享【内网…

PPOCRV3文本识别模型精度损失问题解决

PPOCRV3文本识别模型精度损失问题解决 1. 得到可用的ncnn模型2. 先看问题3. 快速解决4. 问题分析5. 最终效果6. 结语 1. 得到可用的ncnn模型 paddleocr文本识别模型(ch_PPOCRv3_rec_infer)转ncnn模型&#xff0c;我参考了这位大神的博客&#xff0c;基本包括了我遇到的所有问题…

操作系统八股文知识点汇总

1. 程序编译过程 gcc HelloWorld.c -E -o HelloWorld.i 预处理&#xff1a;加入头文件&#xff0c;替换宏。gcc HelloWorld.c -S -c -o HelloWorld.s 编译&#xff1a;包含预处理&#xff0c;将 C 程序转换成汇编程序。gcc HelloWorld.c -c -o HelloWorld.o 汇编&#xff1a;包…

在linux下搭建clash服务

下载clash并配置 clash安装包 一般下载名称中带clash-linux-amd64的包 下载完用gunzip解压&#xff0c;解压后重命名或者链接到系统环境变量目录都行 下载配置信息 wget -O config.yaml [订阅链接] wget -O Country.mmdb https://www.sub-speeder.com/client-download/Coun…

深元边缘计算盒子在社区的应用,提高社区的安全性和生活质量

近年来&#xff0c;随着人工智能技术的不断发展和普及&#xff0c;越来越多的社区开始应用边缘计算盒子AI视觉分析技术&#xff0c;以提高社区的安全性和管理效率。本文将介绍边缘计算盒子AI视觉分析技术在社区中的应用及其优势。 一、边缘计算盒子AI视觉在社区中的应用 1.安防…

uniapp中实现自定义导航栏

整个小程序默认配置存在系统内置导航和tabbar&#xff0c;项目中需求存在自定义的导航。 uniapp中vue封装组件&#xff08;顶部导航、底部tabbar&#xff09;&#xff0c;按照vue的相关语法使用。 在page.json文件中修改配置&#xff1a; 自定义导航组件&#xff1a; 给自定义…

PLM听过很多遍,却依旧不知道是什么?看完这篇你就懂

上周参加展会&#xff0c;很多客户在现场了解到e企拆图解决方案后&#xff0c;向我们咨询了很多问题&#xff0c;发现有几个名词经常被提及&#xff0c;比如PLM、PDM、BOM等。随着技术的爆炸发展&#xff0c;新的名词概念也与日俱增&#xff0c;对于这些名词&#xff0c;可能我…

工贸企业重大事故隐患判定标准,自2023年5月15日起施行

应急管理部发布了《工贸企业重大事故隐患判定标准》&#xff08;自2023年5月15日起施行&#xff09;&#xff0c;适用于判定冶金、有色、建材、机械、轻工、纺织、烟草、商贸等工贸企业重大事故隐患。新修改的安全生产法对建立健全重大事故隐患治理督办制度、督促生产经营单位消…

关于ffmpeg的使用过程中遇到的点(php)

有段日子没更新&#xff0c;最近使用ffmepg&#xff0c;这里记录一下 我这边就直说一下我工作中遇到的注意事项和使用方法&#xff0c;就不太详细说了 首先是安装的问题&#xff0c;windwos的话比较简单&#xff0c;官网下载安装文件&#xff0c;解压之后。设置环境变量 系统…

【react全家桶学习】react中组件定义及state属性(超详/必看)

函数式组件定义及特点 定义&#xff08;核心就是一个函数&#xff0c;返回虚拟dom&#xff09;&#xff1a; import React from reactexport default function index() {return <div>index</div> }特点&#xff1a; 1、适用于【简单组件】的定义2、是一个函数&a…

【三维重建】NeRF原理+代码讲解

文章目录 一、技术原理1.概览2.基于神经辐射场&#xff08;Neural Radiance Field&#xff09;的体素渲染算法3.体素渲染算法4.位置信息编码&#xff08;Positional encoding&#xff09;5.多层级体素采样 二、代码讲解1.数据读入2.创建nerf1.计算焦距focal与其他设置2.get_emb…

1690_Python中的复数数据类型

全部学习汇总&#xff1a;GreyZhang/python_basic: My learning notes about python. (github.com) 之前总结的知识中设计的数据类型有整形、浮点、字符串等&#xff0c;这些类型表示的都是一个单独的独立数据对象。在Python有也有表示复数改变的数据类型&#xff0c;也就是下…

Gradio入门到进阶全网最详细教程[二]:快速搭建AI算法可视化部署演示(侧重参数详解和案例实践)

常用的两款AI可视化交互应用比较&#xff1a; Gradio Gradio的优势在于易用性&#xff0c;代码结构相比Streamlit简单&#xff0c;只需简单定义输入和输出接口即可快速构建简单的交互页面&#xff0c;更轻松部署模型。适合场景相对简单&#xff0c;想要快速部署应用的开发者。 …

千云物流 -测试服务器准备 -iotdb,redis

服务器准备 准备CentOS-7-x86_64-DVD-2009.iso镜像 链接&#xff1a;https://pan.baidu.com/s/1rNkfoeHOuYv0OmitWVDNsQ?pwdjanl 提取码&#xff1a;janl 安装服务器需要的命令yum update yum install net-tools.x86_64 -y yum install zip unzip -y ## 安装jdk到当前机器&am…

MySQL查看索引语句:SHOW INDEX 详细讲解

概述&#xff1a; SHOW INDEX语句是MySQL中用于查看表索引信息的语句。它提供了有关表中索引的详细信息&#xff0c;包括索引名称、索引类型、关联的列等。以下是SHOW INDEX的详细说明&#xff1a; 语法&#xff1a; SHOW INDEX FROM table_name [FROM db_name] [WHERE cond…

python海龟库教学

海龟库&#xff1a; 海龟绘图 “小海龟”turtle是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面坐标系中移动&…