我在接受采访时被问到这个问题。
问题: 二叉树,我们也会给出相应子树的高度。然后我们必须按顺序在特定位置找到一个元素。
例如:树结构为: D (根节点)[subtree-size = 6] - > B,F (D的子节点)[子树大小= 2] - > A,C,E,G (叶节点)[subtree-size = 0]。
总共有3个级别: 0级:D; 等级1 :B,F; 等级2 :A,C,E,G
我们必须按顺序计算特定订单/位置的节点,比如说p。如果p = 2,那么节点将是B( inorder遍历)。
我的解决方案:我建议我们需要进行一次intra遍历(通过BFS / DFS)然后我们可以给出第i个顺序节点,时间复杂度为O(n)
现在我被问到我可以根据子树大小信息改进解决方案。但我无法想出任何可以减少时间复杂度的子树大小的方法。
子树大小信息可以减少时间复杂度吗?如果是,请分享算法/伪代码。
答案 0 :(得分:5)
如果我们想在inorder遍历中的第i个位置找到元素:
i-1
个节点,我们知道我们正在寻找根。i
个或更多节点,它将在左子树中。i-1
,它将在正确的子树中。i
来递归重复此操作。更具体地说,我们需要通过左子树的大小加上一个i
减少每当我们去右子树,作为树的序遍历将在原有的序遍历该位置开始。当转到左子树时,我们不需要更改i
,因为该子树的inorder遍历将从原始inorder遍历的起始位置开始。因此,在伪代码中,我们可以执行以下操作:
currentNode = root
while true
if getSubtreeCount(currentNode.left) == i-1
return currentNode
else if getSubtreeCount(currentNode.left) < i-1
currentNode = currentNode.left
else
currentNode = currentNode.right
i -= getSubtreeCount(currentNode.left) + 1
这将为我们提供O(treeHeight)
的运行时间。
示例:强>
假设我们有一棵树:
D
/ \
B F
/ \ / \
A C E G
假设我们正在寻找inorder遍历中的第二个位置。我们从D开始。我们看到左子树有3个节点,所以我们知道第二个位置在左子树中。看B,我们看到左子树有1个节点,所以我们知道B位于第2位。
假设我们正在寻找inorder遍历中的第5个位置。我们从D开始。我们看到左子树有3个节点,所以我们知道第6个位置在右子树中。看看F,我们现在寻找第一个位置,因为在我们到达以F为根的子树之前,在顺序遍历中有4个节点。我们看到左子树有1个节点,所以我们知道子树包含第一个位置的节点。看看E,我们看到左子树有0个节点,所以我们知道E在这个子树的第一个位置,即我们正在寻找的节点。