0x00 题目
序列化
是将数据结构或对象转换为一系列位的过程
以便它可以存储在文件或内存缓冲区中
或通过网络连接链路传输
以便稍后在同一个或另一个计算机环境中重建
设计一个算法来序列化和反序列化 二叉搜索树
对序列化/反序列化算法的工作方式没有限制
只需确保 二叉搜索树
可以序列化为 字符串
并且可以将该字符串 反序列化
为最初的 二叉搜索树
编码的字符串应尽可能紧凑
0x01 思路
普通二叉树
的序列化,需要加上 空节点
才能保证最后反序列化,得到的树是 唯一的
二叉搜索树
,它的 中序遍历
是 有序
的
有了中序遍历之后,任意给出 前序
遍历或者 后序
遍历
都可以构造一个 唯一的
二叉树
所以二叉搜索树 不需要
序列化 空节点
粟子:
2
/ \
1 3
前序
遍历进行序列化之后是:
2 1 3
反序列化过程:
先把字符串转成数组
因为是前序遍历,所以第一个元素 2
是 根节点
然后找出左右子树的 分界点
由于是二叉搜索树,根据它的性质
1
比 2
小,所以 1
肯定在 2
的 左
子树
3
比 2
大,所以 3
肯定在 2
的 右
子树
0x02 解法
语言:Swift
树节点:TreeNode
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init() { self.val = 0; self.left = nil; self.right = nil; }
public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
self.val = val
self.left = left
self.right = right
}
}
解法:
序列化
func serialize(_ root: TreeNode?) -> String {
guard let root = root else { return "" }
var arr = [String]()
func dfs(_ root: TreeNode?) {
guard let root = root else { return }
// 前序遍历
arr.append(String(root.val))
dfs(root.left)
dfs(root.right)
}
dfs(root)
// 转成字符串,返回
return arr.joined(separator:",")
}
反序列化
func deserialize(_ data: String) -> TreeNode? {
// 先转成数组
var arr = [Int]()
let strs = data.split(separator:",")
for str in strs {
arr.append(Int(str)!)
}
func build(_ arr: [Int], _ left: Int, _ right: Int) -> TreeNode? {
if left > right { return nil }
let val = arr[left]
var root = TreeNode(val)
// 查找分界点
var i = left + 1
while i <= right && arr[i] < arr[left] {
i += 1
}
root.left = build(arr, left + 1, i - 1)
root.right = build(arr, i, right)
return root
}
return build(arr, 0, arr.count-1)
}