题目概述
- 算法说明
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树。 - 测试用例
输入:
{8,6,10,5,7,9,11}
输出:
{8,6,10,5,7,9,11}
输入:
{5,4,#,3,#,2}
输出:
{5,4,#,3,#,2}
解析&参考答案
- 解析
- 按照指定的方式序列化,此处对叶子节点的左右节点都用#来表示(与牛客上的思路有一点区别)。
- 参考答案
vim jz61.go
package main
import (
"fmt"
"strconv"
"strings"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func Serialize(root *TreeNode) *TreeNode {
return &TreeNode{}
}
func SerializePre(root *TreeNode) string {
if root == nil {
return "#"
}
ret := ""
ret = ret + strconv.Itoa(root.Val) + "," + SerializePre(root.Left) + "," + SerializePre(root.Right)
return ret
}
var index = -1
func DeSerializePre(str []string) *TreeNode {
index++
if index > len(str) {
return nil
}
v := str[index]
if v != "#" {
value, _ := strconv.Atoi(v)
root := &TreeNode{value, nil, nil}
root.Left = DeSerializePre(str)
root.Right = DeSerializePre(str)
return root
} else {
return nil
}
}
func main() {
root := &TreeNode{10, &TreeNode{5, &TreeNode{4, nil, nil}, &TreeNode{7, nil, nil}},
&TreeNode{12, nil, nil}}
treeStr := SerializePre(root)
fmt.Println(treeStr)
newRoot := DeSerializePre(strings.Split(treeStr, ","))
fmt.Println(SerializePre(newRoot))
}
注意事项
- 牛客网中若某个节点是叶子节点,那么不设置#标识符号,若某个节点的的左或右节点为空,那么设置为#,其对应的案例2似乎有点问题。
说明
- 当前使用 go1.15.8
- 参考 牛客网--剑指offer
标题中jzn(n为具体数字)代表牛客网剑指offer系列第n号题目,例如 jz01 代表牛客网剑指offer中01号题目。
注意!!!
- 笔者最近在学习 golang,因此趁机通过数据结构和算法来进一步熟悉下go语言
- 当前算法主要来源于剑指 offer,后续会进一步补充 LeetCode 上重要算法,以及一些经典算法
- 此处答案仅为参考,不一定是最优解,欢迎感兴趣的读者在评论区提供更优解