我在二叉树中遇到问题,当我遇到问题时,在完整二叉树的最后一级找到最合适的节点,这里的问题是我们必须在O(n)时间内完成是一个停止点,通过遍历所有元素,在O(n)中执行它很简单,但是有没有办法以低于O(n)的任何复杂度执行此操作,我已经通过互联网浏览了很多,而且我无法# 39;得到关于这件事的任何事情。 提前谢谢。
答案 0 :(得分:1)
是的,您可以通过执行二进制搜索的变体在O(log(n)^2)
中执行此操作。
这可以通过首先进入leftest元素 1 ,然后到第二个leftest元素,然后到第四个leftest元素,第8个,......直到你发现没有这样的元素。
假设您找到的最后一个元素是i
,而您没有找到的第一个元素是2i
。
现在您可以在该范围内进行二元搜索。
这是O(log(n/2)) = O(logn)
次迭代,并且由于每次迭代都在整个树上进行,所以总共O(log(n)^2)
次。
(1)在这里和下面,“x leftest元素”仅指树中最深层的节点。
答案 1 :(得分:0)
由于它是一个完整的二叉树,遍历所有正确的节点直到到达叶子将采用O(logN),而不是O(N)。在常规二叉树中,它需要O(N),因为在最坏的情况下,所有节点都排成一行,但由于它是一个完整的二叉树,所以它不能
答案 2 :(得分:0)
我假设你知道节点的数量。让n
这样的数字。
在完整的二叉树中,级别i
的节点数量是级别i - 1
的两倍。
因此,您可以在n
之间迭代划分2
。如果有余数,那么n
是一个正确的孩子;否则,是一个左孩子。无论是否存在余数,都可以存储到序列中,最好是堆栈。
一些如:
Stack<char> s;
while (n > 1)
{
if (n % 2 == 0)
s.push('L');
else
s.push('R');
n = n/2; // n would int so division is floor
}
当while
完成时,堆栈包含最右边节点的路径。
执行while
的次数为log_2(n)
。
答案 3 :(得分:0)
这是具有时间复杂度O(lg n * lg n)和O(lg n)空间复杂度(考虑堆栈存储空间)的递归解决方案。
使用以下代码的迭代版本,可以将空间复杂度降低到O(1)。
// helper function
int getLeftHeight(TreeNode * node) {
int c = 0;
while (node) {
c++;
node = node -> left;
}
return c;
}
int getRightMostElement(TreeNode * node) {
int h = getLeftHeight(node);
// base case will reach when RightMostElement which is our ans is found
if (h == 1)
return node -> val;
// ans lies in rightsubtree
else if ((h - 1) == getLeftHeight(node -> right))
return getRightMostElement(node -> right);
// ans lies in left subtree
else getRightMostElement(node -> left);
}
时间复杂度推导-
在每个递归步骤中,我们都在考虑左子树还是右子树,即n / 2个元素的最大高度(lg n)函数调用,
计算高度需要lg n时间-
T(n) = T(n/2) + c1 lgn
= T(n/4) + c1 lgn + c2 (lgn - 1)
= ...
= T(1) + c [lgn + (lgn-1) + (lgn-2) + ... + 1]
= O(lgn*lgn)