每个子树在O(N)时间和O(1)空间中的二叉树中求和?

时间:2017-03-31 15:03:41

标签: algorithm data-structures binary-tree

给定二叉树,我想返回最大和子树的根。

最大子树:树的子树,其所有节点的总和大于任何其他子树的总和。

编辑:节点值是一个整数。

我可以执行以下操作,其中包含O(n ^ 2)。

  1. 计算左子树中所有节点的总和
  2. 计算右子树中所有节点的总和
  3. 如果左子树和右子树的总和以及根的值大于当前的最大总和,则根存储在结果中
  4. 以递归方式调用此函数,左子树为根
  5. 以递归方式调用此函数,右子树为根。 这将需要O(n ^ 2)。
  6. 我可以将其更改为自下而上的方法,并使用散列图将节点存储到sum映射,这将使其成为O(N),但它将占用O(N)空间。

    是否有任何方法/方法,即O(N)时间和O(1)空间?

2 个答案:

答案 0 :(得分:3)

这几乎是你的解决方案,但需要O(n)和O(h)内存。您只需访问每个节点一次。

calculateSum(vertex):
    if not vertex:
        return 0    
    sum = calculateSum(left) + calculateSum(right) + vertex.value
    if (sum > max)
        max = sum
    return sum

答案 1 :(得分:1)

是的,如果您动态计算总和,则可以在O(n) O(h)空格内执行此操作。在迭代树时。 (在这里,h是树的最大高度,它是递归堆栈的大小。)

伪代码:

TreeSum(v):
  if (v == null):
    return 0
  v_sum = TreeSum(v.left) + TreeSum(v.right) + v.value
  # max_sum is some global space variable holding the max_sum.
  # you hold only once such variable.  
  if v_sum > max_sum:
    max_sum = v_sum 
  return v_sum 

完成后,max_value保持最大此类总和的值。
如果您还需要节点本身,请保留一个额外的变量,该变量是指向相关节点的指针,并与max_sum一起修改。

想法是在树上做post order traversal。首先计算每个子树的总和,然后 - 计算根的值。
在计算每个子树的总和时,还要在找到新的“最佳”子树时修改max_sum。