[英]Construct tree with pre-order traversal given
给出一种特殊类型的树,其中所有叶子用L
标记,而其他叶子用N
标记。 每个节点可以有0个或最多2个节点。 给出了树的前序遍历。
给出一个算法来从这个遍历构建树。
这是预订序遍历算法:
Preorder(T)
if (T is not null)
print T.label
Preorder(T.left)
Preorder(T.right)
让我们试着找一个NNLLNL
输入的NNLLNL
。
显然,首先打印根标签。 所以你知道root有标签N
现在算法在左子树上进行递归。 根据输入,这也是N
递归左边的子树,即L
现在你必须回溯,因为你已经到了一片叶子。 输入中的下一个位置也是L
,因此当前节点有一个标有L
的右子节点。 回溯一次。 再次回溯,因为您已添加当前节点的所有子节点(最多2个子节点)。 现在你又回到了原点。 你必须走对,因为你已经离开了。 根据输入,这是N
所以根的正确孩子是N
左边的孩子是L
这是你的树:
N
/ \
N N
/ \ /
L L L
请注意,解决方案不一定是唯一的,但这将为您提供可能的解决方案。
伪代码:
k = 0
input = ... get preorder traversal vector from user ...
Reconstruct(T)
if input[k] == N
T = new node with label N
k = k + 1
Reconstruct(T.left)
Reconstruct(T.right)
else
T = new node with label L
T.left = T.right = null
k = k + 1
使用空节点调用。
后续问题 :给定包含不同节点标签的二叉树的预订和顺序遍历,您如何才能唯一地重建树?
这是我的golang版本,用于解决leetcode中有关树的许多问题。
// NewPreorderTree returns preorder tree relate to nums, nums must has not Ambiguity.
// -1 in nums represents child is null.
//
// Example 1:
// Input: [1, 2, 3]
// Generate:
// 1
// /
// 2
// /
// 3
//
// Example 2:
// Input: [1, 2, -1, -1, 3] or [1, 2, -1, -1, 3, -1, -1]
// Generate:
// 1
// / \
// 2 3
func NewPreorderTree(nums ...int) *TreeNode {
return (&preorderTree{nums}).constructTree()
}
type preorderTree struct {
nums []int
}
func (p *preorderTree) constructTree() *TreeNode {
if len(p.nums) == 0 {
return nil
}
if p.nums[0] == -1 {
p.nums = p.nums[1:]
return nil
}
root := &TreeNode{Val: p.nums[0]}
p.nums = p.nums[1:]
root.Left = p.constructTree()
root.Right = p.constructTree()
return root
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.