可视化图解算法37:序列化二叉树-II

news2025/5/13 17:04:41

1. 题目

描述

请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。

二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过某种符号表示空节点(#)

二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,可以根据层序遍历的方案序列化,如下图:

层序序列化(即用函数Serialize转化)如上的二叉树转为"{1,2,3,#,#,6,7}",再能够调用反序列化(Deserialize)将"{1,2,3,#,#,6,7}"构造成如上的二叉树。

当然你也可以根据满二叉树结点位置的标号规律来序列化,还可以根据先序遍历和中序遍历的结果来序列化。不对序列化之后的字符串进行约束,所以欢迎各种奇思妙想。

数据范围:节点数 n≤100,树上每个节点的值满足 0≤val≤150

要求:序列化和反序列化都是空间复杂度 O(n),时间复杂度 O(n)

示例1

输入:

{1,2,3,#,#,6,7}

返回值:

{1,2,3,#,#,6,7}

说明:

如题面图    

示例2

输入:

{8,6,10,5,7,9,11}

返回值:

{8,6,10,5,7,9,11}

2. 解题思路

本题分为两部分,即二叉树的序列化与反序列化。上一篇文章《可视化图解算法36:序列化二叉树-I》讲解的是通过前序遍历的方法完成二叉树的序列化与反序列化,这一篇文章讲解通过层序遍历完成二叉树的序列化与反序列化。

先来看二叉树的序列化(将二叉树序列化为字符串):

可以看出二叉树的节点值是通过层序遍历的方式转换为字符串的(空节点字符串为#),对于层序遍历可以通过队列来辅助完成(二叉树层序遍历详细内容参考:《可视化图解算法23:二叉树的层序遍历》)。具体思路为:

  1. 创建队列,根节点入队列;

  2. 节点出队列,出队列的节点值构成字符串,再将左右子树入队列;

    注:左右子树有可能为null,也需要入队列。

  3. 左右子树出队列,出队列的节点值构成字符串的字符,再将出队列节点的左右子树入队列,如此循环往复。

再来看二叉树的反序列化(将字符串转换为二叉树):

二叉树序列化的时候是通过层序遍历的方法,反序列化的时候需要与此相对应(即也需要通过层序遍历的思想完成)。具体思路为:

  1. 以逗号对字符串进行分割,将其转换为数组;

  2. 基于层序遍历的形式将数组中的字符串转为二叉树的节点并形成二叉树:

    节点出队列,根据数组中的值创建左子树(如果当前值是#,不创建左子树),创建的左子树再入队列;根据数组中的值创建右子树(如果当前值是#,不创建左子树),创建的右子树再入队列;

  3. 依次循环,直至数组中的元素取完。

如果文字描述的不太清楚,你可以参考视频的详细讲解。

  • Python编码:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1372248

  • Java编码:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1367356

  • Golang编码:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1364781

3. 编码实现

核心代码如下:

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * @param root TreeNode类
 * @return TreeNode类
 */
// Serialize 二叉树序列化为字符串
func Serialize(root *TreeNode) string {
	// write code here
	if root == nil {
		return "#"
	}
	// 1. 创建队列并赋值
	queue := []*TreeNode{root}
	res := ""
	// 2. 操作队列(二叉树节点出队列,左右子树入队列)
	for len(queue) > 0 {
		// 2.1 节点出队列
		node := queue[0]
		queue = queue[1:]
		if node == nil { //null节点没有叶子节点,不需要操作
			res += "#" + ","
			continue
		}
		res += strconv.Itoa(node.Val) + ","
		//2.2 左子树入队列
		queue = append(queue, node.Left)
		//2.3 右子树入队列
		queue = append(queue, node.Right)
	}
	res = strings.TrimRight(res[:len(res)-1], ",#") //去掉末尾连续的" ,# "
	return res
}

// Deserialize 字符串反序列化为二叉树
func Deserialize(s string) *TreeNode {
	// write code here
	if s == "#" || strings.TrimSpace(s) == "" {
		return nil
	}
	// 1. 分割(序列化的)字符串
	arr := strings.Split(s, ",")
	// 2. 创建root节点
	rootVal, _ := strconv.Atoi(arr[0])
	root := &TreeNode{Val: rootVal}
	// 3. 操作队列(二叉树节点出队列,左右子树入队列)
	queue := []*TreeNode{root}
	index := 1 // arr对应的索引
	for index < len(arr) {
		// 3.1 节点出队列
		node := queue[0]  // 队列的头节点
		queue = queue[1:] // 删除队列的头节点
		// 3.2 创建左子树并入队列
		if arr[index] != "#" {
			leftVal, _ := strconv.Atoi(arr[index])
			node.Left = &TreeNode{Val: leftVal}
			queue = append(queue, node.Left) //添加左子树到队列
		}
		index++ // 移动索引(不管左子树用到了#还是数值,都需要移动index)
		// 3.3 创建右子树并入队列
		if index < len(arr) && arr[index] != "#" {
			rightVal, _ := strconv.Atoi(arr[index])
			node.Right = &TreeNode{Val: rightVal}
			queue = append(queue, node.Right) // 添加右子树到队列
		}
		index++ // 移动索引的值(不管右子树用到了#还是数值,都需要移动index)
	}
	return root
}

具体完整代码你可以参考下面视频的详细讲解。具体完整代码你可以参考下面视频的详细讲解。
  • Python编码:数据结构笔试面试算法-Python语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Python语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1372248

  • Java编码:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1367356

  • Golang编码:数据结构笔试面试算法-Go语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Go语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1364781

4.小结

二叉树的序列化与反序列化可以通过层序遍历的方法来完成,层序遍历可以通过队列来辅助完成。

《数据结构与算法》深度精讲课程正式上线啦!七大核心算法模块全解析:

        ✅   链表

        ✅   二叉树

        ✅   二分查找、排序

        ✅   堆、栈、队列

        ✅   回溯算法

        ✅   哈希算法

        ✅   动态规划

无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!

  • Python编码实现:数据结构笔试面试算法-Python语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Python语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ss897667807

  • Java编码实现:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ss161443488

  • Golang编码实现:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ss63997

对于二叉树的相关算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:百川东到海,何时复西归?

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

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

相关文章

C++GO语言微服务和服务发现②

01 创建go-micro项目-查看生成的 proto文件 02 创建go-micro项目-查看生成的main文件和handler ## 创建 micro 服务 命令&#xff1a;micro new --type srv test66 框架默认自带服务发现&#xff1a;mdns。 使用consul服务发现&#xff1a; 1. 初始consul服务发现&…

【Web前端开发】CSS基础

2.CSS 2.1CSS概念 CSS是一组样式设置的规则&#xff0c;称为层叠样式表&#xff0c;用于控制页面的外观样式。 使用CSS能够对网页中元素位置的排版进行像素控制&#xff0c;实现美化页面的效果&#xff0c;也能够做到页面的样式和结构分离。 2.2基本语法 通常都是&#xff…

Git实战经验分享:深入掌握git commit --amend的进阶技巧

一、工具简介 git commit --amend是Git版本控制系统的核心补救命令&#xff0c;主要用于修正最近一次提交的元数据。该命令不会产生新的提交记录&#xff0c;而是通过覆盖原提交实现版本历史的整洁性&#xff0c;特别适合在本地仓库进行提交优化。 二、核心应用场景 提交信息…

PTA:jmu-ds-最短路径

给定一个有向图&#xff0c;规定源点为0&#xff0c;求源点0到其他顶点最短路径。###你要实现的 函数接口定义&#xff1a; void Dijkstra(MGraph g,int v);//源点v到其他顶点最短路径 裁判测试程序样例&#xff1a; #include <stdio.h> #include <iostream> …

WEB UI自动化测试之Pytest框架学习

文章目录 前言Pytest简介Pytest安装Pytest的常用插件Pytest的命名约束Pytest的运行方式Pytest运行方式与unittest对比主函数运行命令行运行执行结果代码说明 pytest.ini配置文件方式运行&#xff08;推荐&#xff09;使用markers标记测试用例 pytest中添加Fixture&#xff08;测…

深入理解 iOS 开发中的 `use_frameworks!`

在使用 CocoaPods 管理 iOS 项目依赖时&#xff0c;开发者经常会在 Podfile 文件中看到一个配置选项&#xff1a;use_frameworks!。本文将详细介绍这个配置选项的含义&#xff0c;以及如何决定是否在项目中使用它。 一、什么是 use_frameworks! 在 CocoaPods 中引入第三方库时…

矩阵置零算法讲解

矩阵置零算法讲解 一、问题描述 给定一个 (m \times n) 的矩阵,如果一个元素为 (0) ,则将其所在行和列的所有元素都设为 (0) 。要求使用原地算法,即在不使用额外矩阵空间的情况下完成操作。 二、解题思路 暴力解法 最直观的想法是遍历矩阵,当遇到 (0) 元素时,直接将其…

二本计算机,毕业=失业?

我嘞个豆&#xff0c;二本计算机&#xff0c;毕业即失业&#xff1f;&#xff01; 今天咱们聊聊普通院校计算机专业的学生未来的发展方向。有些话可能不太中听&#xff0c;但希望大家能理性看待。 首先得承认&#xff0c;对于普通双非和二本的学生来说&#xff0c;就业率加上…

[docker基础二]NameSpace隔离实战

目录 一 实战目的 二 基础知识 1)dd 命令详解 2)mkfs命令详解 3)df命令详解 4)mount 命令详解 5)unshare命令详解 三 实战操作一(PID隔离) 四 实战操作二(MOunt隔离) 1&#xff09;创建 Mount 隔离进程 2&#xff09;在新进程里边&#xff0c;创建空白文件&#…

Day22打卡-复习

复习日 仔细回顾一下之前21天的内容&#xff0c;没跟上进度的同学补一下进度。 作业&#xff1a; 自行学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号人员生还预测https://www.kaggle.com/competitions/titanic/overview K…

uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图)

uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图) 代码示下,不再赘述。 动作面板组件:https://nutui-uniapp.netlify.app/components/feedback/actionsheet.html 项目背景 业务需求 描述: uniapp + vue3 + 京东Nut框架:实现登录弹框组…

C++类和对象--中阶

C类和对象中阶 01. 类的6个默认成员函数 在 C 中&#xff0c;类有 6 个特殊的默认成员函数&#xff08;不是 6 个构造函数&#xff09;&#xff0c;它们会在特定情况下由编译器自动生成。包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造和赋值运算符重载&#xff0c;取…

数据签名在区块链中的独特应用与挑战

随着信息技术的飞速发展&#xff0c;分布式系统因其高效、可靠、可扩展等显著优点&#xff0c;在众多领域得到了极为广泛的应用。分布式系统通过网络将多个独立的计算节点连接在一起&#xff0c;协同完成复杂的任务&#xff0c;这种架构使得系统具备了强大的容错能力和负载均衡…

数据可视化大屏——物流大数据服务平台(二)

代码分析&#xff1a; 物流大数据平台代码分析 这是一个基于 Bootstrap 和 ECharts 构建的物流大数据平台前端页面&#xff0c;设计采用了经典的三栏布局&#xff0c;主要展示河南省及全国的物流数据可视化内容。下面从多个维度进行分析&#xff1a; 1. 页面结构分析 整体采…

Maven 处理依赖冲突

Maven处理依赖冲突 什么是依赖冲突&#xff1f;如何解决&#xff1f;Maven自动处理依赖冲突的规则路径优先原则第一声明优先原则注意 子模块覆盖父模块父模块声明dependency子模块覆盖dependency父模块声明dependencyManagement 子模块覆盖dependency父模块声明dependencyManag…

5.12第四次作业

实验要求&#xff1a;完成上图内容&#xff0c;要求五台路由器的环回地址均可以相互访问 AR1 AR2 AR3 AR4 AR5 AS 200 ospf配置 AR2 AR3 AR4 BGP配置 AR1&#xff08;AS100&#xff09; AR2&#xff08;AS200&#xff09; AR4 AR5&#xff08;AS300&#xff09; 结果

【Lattice FPGA 开发】Diamond在线调试Reveal逻辑乱跳的解决

在Vivado中在always块中写逻辑时如果出现always块中的异步复位敏感词在块内部未使用的情况&#xff0c;如下例的rst&#xff1a; always (posedge clk or posedge rst) begin if(~tx_sense_flag)o_rd_adr < d1;else if((o_rd_adr d94) & (bit_cnt d7))o_rd_adr <…

Go语言——kratos微服务框架使用

文章目录 一、安装依赖二、创建项目三、初始化项目四、使用git_bash命令终端运行命令五、创建自己的项目1、修改app.proto3、internal/service/app.go4、修改internal/service/service.go文件5、创建internal/biz/content.go文件6、修改internal/biz/biz.go文件7、创建internal…

hiveserver2与beeline进行远程连接hive配置及遇到的问题

1、hiveserver2 参与用户模拟功能&#xff0c;因为开启后才能保证各用户之间的权限隔离。 1.1、配置 $HADOOP_HOME/etc/hadoop/core-site.xml <!--配置所有节点的root用户都可作为代理用户--> <property><name>hadoop.proxyuser.root.hosts</name>&…

Stable Diffusion进阶之Controlnet插件使用

前面已经对Stable Diffusion的文生图和图生图的操作界面做了详细的介绍&#xff0c;接下来会介绍Stable Diffusion的进阶部分Controlnet插件的使用。往期文章详见&#xff1a; 爆肝整理&#xff01;Stable Diffusion的完全使用手册&#xff08;一&#xff09;爆肝整理&#xff…