【问题标题】:Time complexity of checking if a binary tree is balanced检查二叉树是否平衡的时间复杂度
【发布时间】:2015-12-14 16:41:53
【问题描述】:

我正在练习一些面试问题,并试图弄清楚我的解决方案的时间复杂度以确定给定的二叉树是否平衡。

我相信解决方案 2 的时间复杂度为 O(n),而解决方案 1 的时间复杂度为 O(n^2)。这是因为在解决方案 1 中,您递归到树的底部以检查树是否平衡并检查子树高度的差异。额外的复杂性来自于我们向树的根部更高的备份,get_height 仍然沿树向下递归以计算高度。因此,再次沿着树向下旅行--> O(n^2)

解决方案 2 首先比较高度的事实意味着,当我们向上移动树时,我们不必再向下检查子树高度。

帮手:

def get_height(root):
    if root is None:
        return 0
    else:
        return max(get_height(root.left), get_height(root.right)) + 1

解决方案 1:

def is_balanced(root):
    if root is None:
        return True
    else:
        return is_balanced(root.right) and is_balanced(root.left) and (abs(get_height(root.left) - get_height(root.right)) < 2)

解决方案 2:

def is_balanced2(root):
    if root is None:
        return True
    else:
        return (abs(get_height(root.left) - get_height(root.right)) < 2) and is_balanced(root.right) and is_balanced(root.left)

检查时差的代码:

s = time.time()
print("result: {}".format(is_balanced(a)))
print("time: {}".format(time.time() - s))

s = time.time()
print("result: {}".format(is_balanced2(a)))
print("time: {}".format(time.time() - s))

不平衡树的结果:

result: False
time: 2.90870666504e-05    # solution 1
result: False
time: 1.50203704834e-05    # solution 2

【问题讨论】:

    标签: python algorithm tree


    【解决方案1】:

    我认为解决方案 2 的时间复杂度为 O(n),而解决方案 1 的时间复杂度为 O(n^2)。

    我不相信,如下所述。

    ...在解决方案 1 中,您递归到树的底部以检查树是否平衡并检查子树高度的差异。额外的复杂性来自于我们向树的根部更高的备份,get_height 仍然沿树向下递归以计算高度。因此,再次沿着树向下行进 --> O(n^2)。

    事情没那么简单。假设您在根上调用is_balanced():当它递归访问树中的每个节点时,它调用get_height,它递归地访问其下的子树。对于根,get_height 几乎访问了整个树:N-1 次操作,所以 O(N)。对于根的 2 个孩子中的每一个,get_height 访问他们(大致)一半的树:再次 O(N)。这一直持续到get_height 在 N/2 个叶节点下的 ~N 个None 节点上运行:仍然是 O(N)。树中总共有 ~log2N 个级别,每个级别都进行 O(N) 处理,因此总体复杂度为 O(NlogN)。

    解决方案 2 首先比较高度的事实意味着,当我们向上移动树时,我们不必再向下检查子树高度。

    不。您在解决方案二中所做的更改是执行 is_balancedget_height 检查的顺序。对于两个测试最终都通过的任何树,总处理量 - 因此 big-O 效率 - 是不变的。

    另外,您的逻辑不会检查平衡二叉树:您可能需要重新阅读定义。

    【讨论】:

    • 我不确定我的解决方案如何不检查二叉树是否平衡。你能提供一些例子吗?谢谢
    • @Liondancer:考虑Wikipedia here 上的示例树,其中引入了“平衡二叉树具有叶节点的最小可能最大高度(也称为深度)”:对于左边的平衡树,左分支 ABCD 的高度为 3(使用它们的根 = 0 计数),而右分支 E 的高度为 1 ......这不会通过你的 abs(get_height(root.left) - get_height(root.right)) &lt; 2) 条件。正如维基百科所说,
    猜你喜欢
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多