检查二叉树是否平衡的时间复杂度

时间:2015-12-14 00:32:54

标签: python algorithm tree

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

我认为解决方案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

1 个答案:

答案 0 :(得分:4)

  

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

我不相信,如下所述。

  

...在解决方案1中,您递归到树的底部以检查树是否平衡并检查子树高度的差异。额外的复杂性随着我们向树的朝向更高的方向向上移动,get_height仍在向下计算树以计算高度。因此,再次沿树下行 - &gt;为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首先比较高度的事实意味着当我们向上移动树时,我们不必返回检查子树高度。

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

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