基于任意两种遍历序列都可以重建二叉树吗?
答案是不能。只有“先+中”、”后+中“才可以重建,而”先+后“是无法重建的。
这是因为: 先序与后序的最大优势是可以确认根节点的所在(首部或尾部),然后基于中序得到左子树和右子树的尺寸,进而递归分治。但”先+后“拥有类似的知识,即可以知道根节点在何处但无法划分左右子树,因此在线性复杂度下不可解。
重建二叉树和二叉树的反序列化有何区别?
二叉树的序列化对”空节点“进行了标记,而简单的遍历序列由于缺失了空节点信息,因此单序列无法重建二叉树,必须要双序列配合才可以。
从《[算法][面试]二叉树的序列化与反序列化(bfs|先序、后序)》我们已知其仅可在先序、后序遍历序列化的情况下进行反序列化。
代码:
def rebuild_pre_in(preorder
: List
[int], inorder
: List
[int]) -> TreeNode
or None:
if len(preorder
) == 0:
return None
root
= TreeNode
(preorder
[0])
root_in_id
= inorder
.index
(preorder
[0])
root
.left
= rebuild_pre_in
(preorder
[1:1 + root_in_id
], inorder
[:root_in_id
])
root
.right
= rebuild_pre_in
(preorder
[1 + root_in_id
:], inorder
[root_in_id
+ 1:])
return root
def rebuild_pre_pos(preorder
: List
[int], posorder
: List
[int]) -> TreeNode
or None:
pass
def rebuild_in_pos(inorder
: List
[int], posorder
: List
[int]) -> TreeNode
or None:
if len(posorder
) == 0:
return None
root
= TreeNode
(posorder
[-1])
root_in_id
= inorder
.index
(posorder
[-1])
root
.left
= rebuild_in_pos
(inorder
[:root_in_id
], posorder
[:root_in_id
])
root
.right
= rebuild_in_pos
(inorder
[root_in_id
+ 1:], posorder
[root_in_id
:-1])
return root