【刷题日记】验证二叉树的前序序列化

简介: 本次刷题日记的第 51 篇,力扣题为:验证二叉树的前序序列化,中等

本次刷题日记的第 51 篇,力扣题为:验证二叉树的前序序列化中等

一、题目描述:

image.png

又是一个二叉树的题,二叉树的题怎么地,比多叉树简单吧?其实他们解法都一样


二、这道题考察了什么思想?你的思路是什么?

题目的要求比较明确,就是给出一个字符串,字符串中包含数字,逗号,井号, 分别表示二叉树节点,字符的间隔,以及空节点

然后我们通过某种方式来校验,给出的这一串字符串是符合二叉树的前序遍历的结果

看到这个这个要求其实可能会嘴角一笑,咱们简单的按照前序遍历的方式,将字符串恢复成二叉树是不是就可以了?

但是题目特地强调了一点,咱们不能重建树,因此我们只能另寻他法


分析

稍加思考,我们的注意力可以转移到字符串中某些字符的个数上来,我们看看下图

image.png

对于二叉树而言,一个节点可能有 2 个子节点,也有可能是 1 个子节点,那么根据题目中的意思,那么可能是在字符串中补充 具体的两个数字,例如 2,3

image.png

或者是 一个空节点 # 号和 1 数字,例如 #,3 或者 3,#

image.png

那么当我们去遍历字符串的时候,如果遇到的是 # 号,那么我们就把待补充的节点数减去 1 ,如果是一个数字的话,那么仍然把待补充的节点数减去 1,且在继续补充 2 个节点进去

image.png

此处我们可不能直接将上一层的待补充节点数和这一层的待补充节点数混为一谈哦,是需要分开的

这么看来,我们关注的点就是要放在给出的字符串中的字符,我们从头开始遍历,按照上述逻辑进行记录需要补充的字符

我们可以使用栈的方式来处理,继续遍历,如果遇到 # 号,我们就把待补充的节点数(栈顶的数字)减去 1 ,如果是一个数字的话,那么仍然把待补充的节点数减去 1,且在继续补充 2 个节点到栈中

  • 在遍历过程中,如果我们还没有遍历完毕题目给出的字符串,可是待补充的节点已经没有了,说明给出字符串是不符合要求的
  • 当然,如果遍历完全字符串,发现我们记录的待补充的节点数还有,那么也是有问题的,说明字符串也并不是一个完整的二叉树前序遍历
  • 因此,只有当我们完全遍历完字符串,且我们记录的待补充的节点数也是 0 的时候,我们才能判定这个字符串,是一个完整的二叉树前序遍历

三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码

此处需要注意,我们初始化待补充节点的时候,默认给 1 个节点,因为,我们需要放根节点,根节点只有 1 个

编码如下:

func isValidSerialization(preorder string) bool {
    n := len(preorder)
    help := []int{1}
    // 遍历给出的 字符串
    for i := 0; i < n; {
        if len(help) == 0 {
            return false
        }
        // 校验字符串中给出的 3 中情况,数字,逗号,# 号
        if preorder[i] == ',' {
            i++
        } else if preorder[i] == '#' {
            help[len(help)-1]--
            if help[len(help)-1] == 0 {
                help = help[:len(help)-1]
            }
            i++
        } else {
            for i < n && preorder[i] != ',' {
                i++
            }
            help[len(help)-1]--
            if help[len(help)-1] == 0 {
                help = help[:len(help)-1]
            }
            help = append(help, 2)
        }
    }
    return len(help) == 0
}

四、总结:

image.png

时间复杂度很明确,我们遍历了一遍给出的字符串,因此时间复杂度是 O(n)空间复杂度也是 O(n) ,因为咱们开辟了栈空间,这个空间会涉及了二叉树的每一个节点

原题地址:331. 验证二叉树的前序序列化

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~



相关文章
|
5月前
|
Go
golang力扣leetcode 297.二叉树的序列化与反序列化
golang力扣leetcode 297.二叉树的序列化与反序列化
38 0
|
2月前
|
存储 算法 Python
【Leetcode刷题Python】297. 二叉树的序列化与反序列化
LeetCode第297题"二叉树的序列化与反序列化"的Python语言解决方案,包括序列化二叉树为字符串和反序列化字符串为二叉树的算法实现。
23 5
|
5月前
|
Java Go 算法
Golang每日一练(leetDay0100) 二叉树序列化和反序列化
Golang每日一练(leetDay0100) 二叉树序列化和反序列化
51 0
Golang每日一练(leetDay0100) 二叉树序列化和反序列化
|
5月前
|
Go Python 算法
Python每日一练(20230412) 队列实现栈、二叉树序列化、交换链表节点
Python每日一练(20230412) 队列实现栈、二叉树序列化、交换链表节点
766 0
Python每日一练(20230412) 队列实现栈、二叉树序列化、交换链表节点
|
5月前
|
算法 前端开发
331. 验证二叉树的前序序列化
331. 验证二叉树的前序序列化
46 0
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
存储 开发框架 .NET
解锁SqlSugar新境界:利用Serialize.Linq实现Lambda表达式灵活序列化与反序列化,赋能动态数据查询新高度!
【8月更文挑战第3天】随着软件开发复杂度提升,数据查询的灵活性变得至关重要。SqlSugar作为一款轻量级、高性能的.NET ORM框架,简化了数据库操作。但在需要跨服务共享查询逻辑时,直接传递Lambda表达式不可行。这时,Serialize.Linq库大显身手,能将Linq表达式序列化为字符串,实现在不同服务间传输查询逻辑。结合使用SqlSugar和Serialize.Linq,不仅能够保持代码清晰,还能实现复杂的动态查询逻辑,极大地增强了应用程序的灵活性和可扩展性。
111 2
|
8天前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
14天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第3天】在Java编程的世界里,对象序列化与反序列化是实现数据持久化和网络传输的关键技术。本文将深入探讨Java序列化的原理、应用场景以及如何通过代码示例实现对象的序列化与反序列化过程。从基础概念到实践操作,我们将一步步揭示这一技术的魅力所在。
|
28天前
|
存储 XML JSON
用示例说明序列化和反序列化
用示例说明序列化和反序列化
15 1