在another question中关于找到计算二叉树直径的算法,提供以下代码作为问题的可能答案。
public static int getDiameter(BinaryTreeNode root) {
if (root == null)
return 0;
int rootDiameter = getHeight(root.getLeft()) + getHeight(root.getRight()) + 1;
int leftDiameter = getDiameter(root.getLeft());
int rightDiameter = getDiameter(root.getRight());
return Math.max(rootDiameter, Math.max(leftDiameter, rightDiameter));
}
public static int getHeight(BinaryTreeNode root) {
if (root == null)
return 0;
return Math.max(getHeight(root.getLeft()), getHeight(root.getRight())) + 1;
}
在评论部分,据说上述代码的时间复杂度为O(n ^ 2)。在给定getDiameter
函数的调用时,将为左右子树调用getHeight
和getDiameter
函数。
让我们考虑二叉树的平均情况。高度可以在Θ(n)时间计算(对于最坏情况也是如此)。那么我们如何计算getDiameter
函数的时间复杂度?
我的两个理论
Τ(n)= 4T(n / 2)+Θ(1)=Θ(n ^ 2),考虑高度计算 (相同?)子问题。
T(n)= 2T(n / 2)+ n +Θ(1)=Θ(nlogn),n = 2 * n / 2用于高度计算?
感谢您的时间和精力!
答案 0 :(得分:2)
有一点困惑在于您认为二叉树是平衡的。实际上,它可以是一条线。在这种情况下,我们需要从根到叶子的n
操作来查找从根的子项到叶子的高度n - 1
,依此类推。这使得O(n^2)
操作可以单独找到所有节点的高度。
如果在找到直径之前独立计算每个节点的高度,则可以优化算法。然后我们会花费O(n)
时间来寻找所有高度。然后找到直径的复杂性将是以下类型:
T(n)= T(a)+ T(n-1-a)+ 1
其中a
是左子树的大小。这种关系也会给出寻找直径的线性时间。所以总时间是线性的。