【问题标题】:Diameter of Binary Tree - Algorithm Complexity二叉树的直径 - 算法复杂度
【发布时间】:2015-04-13 18:56:39
【问题描述】:

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;
}

在 cmets 部分中,据说上述代码的时间复杂度为 O(n^2)。在给定调用getDiameter 函数时,会为左右子树调用getHeightgetDiameter 函数。

让我们考虑二叉树的平均情况。高度可以在 Θ(n) 时间计算(对于最坏的情况也是如此)。那么我们如何计算getDiameter函数的时间复杂度呢?

我的两个理论

  1. Τ(n) = 4T(n/2) + Θ(1) = Θ(n^2),考虑高度计算 (相同?)子问题。

  2. T(n) = 2T(n/2) + n + Θ(1) = Θ(nlogn), n = 2*n/2 用于高度计算?

感谢您的时间和精力!

【问题讨论】:

    标签: algorithm binary-tree time-complexity


    【解决方案1】:

    混淆的一点是你认为二叉树是平衡的。实际上,它可以是一条线。在这种情况下,我们需要从根到叶子的n 操作来找到高度,从根的孩子到叶子的n - 1 等等。这提供了O(n^2) 操作来单独查找所有节点的高度。

    如果在找到直径之前独立计算每个节点的高度,则可以优化算法。然后我们将花费O(n) 时间寻找所有高度。那么找到直径的复杂性将是以下类型:

    T(n) = T(a) + T(n - 1 - a) + 1

    其中a 是左子树的大小。这种关系也将给出寻找直径的线性时间。所以总时间是线性的。

    【讨论】:

    • 你对最坏的情况是正确的,我得到了另一个公式,谢谢!我们还可以在计算直径的同时计算高度,从而达到 O(n)。但是,如果我们有一个(几乎)平衡的树并且我们使用上面的代码,那么什么公式正确地描述了时间复杂度?我的第二个猜测是否正确(要计算每个节点 (n) 的高度 (logn),我们需要 nlogn 操作 + O(n) 操作来计算直径)?
    • 第二个猜测我相信πατριωτακι
    • 好的,ευχαριστώ ;) 我不接受这个答案,以防万一其他人想帮忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2019-08-12
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 2020-02-13
    相关资源
    最近更新 更多