大家好,我是 @负雪明烛。👈👈 点击关注,优质题解不间断。
题目大意
首先要明白题意:
- 序列化:把内存中的二叉搜索树转成字符串;
- 反序列化:把字符串恢复成内存中的二叉搜索树。
题目没有限定我们用什么方法,只要求我们序列化后的字符串尽可能紧凑。
解法不固定,只要序列化后的结果,能被反序列化函数还原成一模一样的二叉搜索树(BST),都认为是正确答案。
评测的过程是下面这样:
Codec ser = new Codec();Codec deser = new Codec();String tree = ser.serialize(root);TreeNode ans = deser.deserialize(tree);return ans;
解题方法
前序遍历 + 递归
BST 的基本定义:
- BST 的左子树所有节点都比根节点值小,右子树所有节点都比根节点值大。
只知道树的一种遍历方式,是没法确定这个树的,BST 也不例外。
因此,我的主要思路就是:采用前序遍历的序列化 BST,再根据 BST 的性质进行反序列化。
具体做法如下:
- 前序遍历得到的数组的第一个值就是 BST 的根节点
- 数组后面的这些数中比根节点的值小的是根节点的左子树,比根节点值大的是根节点的右子树
- 递归就可以反序列化出原本的 BST
代码如下:
# Definition for a binary tree node.# class TreeNode(object):# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Codec:def serialize(self, root):vals = []def preOrder(root):if root:vals.append(root.val)preOrder(root.left)preOrder(root.right)preOrder(root)return ','.join(map(str, vals))def deserialize(self, data):if not data or data == '':return Nonevals = map(int, data.split(","))root = TreeNode(vals[0])leftVals = [x for x in vals if x < vals[0]]rightVals = [x for x in vals if x > vals[0]]root.left = self.deserialize(",".join(map(str, leftVals)))root.right = self.deserialize(",".join(map(str, rightVals)))return root# Your Codec object will be instantiated and called as such:# ser = Codec()# deser = Codec()# tree = ser.serialize(root)# ans = deser.deserialize(tree)# return ans
复杂度
- 时间复杂度:序列化是 $O(N)$;反序列化最差达到 $O(N^2)$,因为当树的节点都偏向于一侧的时候,每遍历一个节点,都要对访问剩余的
个节点。
- 空间复杂度:序列化是 $O(N)$;反序列化最差达到 $O(N^2)$,理由同上。
总结
- 没有固定套路的题目,需要自己发掘数据结构的性质,找到合适的解法。
我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
- 在刷题的时候,如果你不知道该怎么刷题,可以看 LeetCode 应该怎么刷?
- 如果你觉得题目太多,想在短时间内快速提高,可以看 LeetCode 最经典的 100 道题。
- 送你一份刷题的代码模板:【LeetCode】代码模板,刷题必会
- 我写的 1000 道 LeetCode 题解,都在这里了,免费拿走。
