题目地址
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
示例 1:
输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
提示:
树中结点数在范围 [0, 10^4] 内
-1000 <= Node.val <= 1000
解法:广度优先搜索遍历BFS(层次遍历)
参考:
指路1
指路2
注意理解题目要求,可以通过序列化函数进行序列化和然后通过反序列化恢复即可,因此答案不唯一,只要你的答案能恢复你的序列化二叉树就行了
1 1
/ \ / \
2 3 2 3
/ \ / \ / \
4 5 nul nul 4 nul
/ / \
6 nul nul
序列化:例子给的序列化过程是二叉树的层序遍历(广度优先)过程,那我也用层序遍历吧,实际上,你可以采用任意方式,比如深度优先的方式。我们利用队列依次将每一层的节点压入和弹出,保证了层序,压入过程压入该层节点的所有子节点,弹出过程弹出该层所有节点,因为这里只需要序列化,我们不必知道节点是哪一层的,所以只需要清空队列即可。
反序列化:反序列化的过程同样需要队列,这个过程是我们模拟序列化的过程,然后依次将val值给我们构建的二叉树节点。
留意函数输入和输出数据的类型:序列化输出字符串,反序列化输入为字符串,不是直接拿来就用,或者直接返回数组就行,要进行一次字符串和数组的转换。
发现很多人割裂了反序列化和序列化的过程,甚至进行反序列化时没有搞清楚序列化的过程,序列化和反序列化是一一对应的,反序列化的方式取决于序列化的方式,而不应该不看序列化只看反序列化的部分,这个过程类似于编码和解码,对同一内容进行反复的编解码,结果不会发生变化,提交没通过的,建议好好看看序列化过程到底是怎么完成的。
序列化:
- 用BFS遍历树,与一般遍历的不同点是不管node的左右子节点是否存在,统统加到队列中
- 在节点出队时,如果节点不存在,在返回值res中加入一个”null“;如果节点存在,则加入节点值的字符串形式
反序列化:
- 同样使用BFS方法,利用队列新建二叉树
- 首先要将data转换成列表,然后遍历,只要不为null将节点按顺序加入二叉树中;同时还要将节点入队
- 队列为空时遍历完毕,返回根节点
代码实现:
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
if not root: return "[]"
queue = collections.deque()
queue.append(root)
res = []
while queue:
node = queue.popleft() # 出队
if node:
res.append(str(node.val))
queue.append(node.left)
queue.append(node.right)
else: res.append("null")
return '[' + ','.join(res) + ']'
# res:['1','2','3','null','null','4','5','null','null','null','null']
# ''.join(res):123nullnull45nullnullnullnull
# '[' + ','.join(res) + ']':[1,2,3,null,null,4,5,null,null,null,null]
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if data=='[]':
return None
# data:[1,2,3,null,null,4,5,null,null,null,null]
# vals:['1','2','3','null','null','4','5','null','null','null','null']
vals, i = data[1:-1].split(','), 1
root = TreeNode(int(vals[0]))
queue = collections.deque()
queue.append(root)
while queue:
node = queue.popleft() # 出队
if vals[i] != "null":
node.left = TreeNode(int(vals[i]))
queue.append(node.left)
i += 1
if vals[i] != "null":
node.right = TreeNode(int(vals[i]))
queue.append(node.right)
i += 1
return root