题目
序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
示例
示例 1:
输入:root = [2,1,3]
输出:[2,1,3]
示例 2:
输入:root = []
输出:[]
思路
树的正反序列化问题:
正序列化:只需要进行树的深度优先遍历即可得到,具体使用何种深度优先遍历方法看题目要求,本题的正序列化应当使用先序遍历
反序列化:一般树的反序列化只有在知道先序和中序或者后序和中序的序列后才能确定一棵树的完整结构。但是本题是一个二叉搜索树,具有一定规律(即左子树的值都比根节点上的值小,右子树上的值都比根节点上的值大)
具体反序列的方法:
将 data 根据分隔符 , 进行分割,假设分割后数组 res 长度为 n,那么 res[0, n - 1]代表完整的子树,我们可以利用「二叉树」特性递归构建,设计递归函数 TreeNode process2(int l, int r, Sring[] res),其含义为利用 res[l, r] 连续段构造二叉树,并返回头结点:
步骤
- res[l]为头结点,其值为 t,在 [l, r] 范围内找到第一个比 t 大的位置 j:
- res[l] 的左子树的所有值均比 t 小,且在 data 中连续存储,我们可以递归处理 [l + 1, j -1] 构建左子树;
- res[l]的右子树的所有值均比 t 大,且在 data 中连续存储,我们可以递归处理 [j,r] 构建右子树。
题解
# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Codec: def serialize(self, root: TreeNode) -> str: """Encodes a tree to a single string. """ return str(self.process(root, [])) def process(self, root, res): if root is None: return res.append(root.val) self.process(root.left, res) self.process(root.right, res) return res def deserialize(self, data: str) -> TreeNode: """Decodes your encoded data to tree. """ if data == 'None': return None else: data = list(data.strip('[').strip(']').split(',')) return self.process2(0, len(data)-1, data) def process2(self,l, r, res): if l > r: return None j,t = l+1, int(res[l]) ans = TreeNode(t) while j <= r and int(res[j]) <= t: j += 1 ans.left = self.process2(l + 1, j-1, res) ans.right = self.process2(j, r, res) return ans # Your Codec object will be instantiated and called as such: # Your Codec object will be instantiated and called as such: # ser = Codec() # deser = Codec() # tree = ser.serialize(root) # ans = deser.deserialize(tree) # return ans