将二叉树划分为两个树,使其直径差小于特定值K

时间:2017-04-07 16:38:27

标签: tree dynamic-programming graph-theory depth-first-search breadth-first-search

给出二叉树。我们必须remove an edge并将其划分为two trees,以便difference of the diameter of the two new trees is less than a specified value K

我有一个天真的解决方案,选择each edge并检查条件,如果通过删除该边缘我们可以获得解决方案(我们可以通过使用两个DFS/BFS来计算直径)。这使我的解决方案O(n ^ 2)。

有人可以建议我采用比我更好的方法吗?

我认为我们可以使用动态编程,但我无法将其可视化。

1 个答案:

答案 0 :(得分:0)

每个节点足以计算它下面树的高度。对于叶节点,它为0,对于其他节点,它为max(height of children) + 1。这是通过tree post-order traversing完成的。

二叉树的直径为height of left child + height of right child + 1。对于一般树,它是(sum of two max heights) + 1

算法的想法是从根开始并“爬下”更高的孩子,同时检查孩子的子树的直径和树的其余部分之间的差异。这可以通过计算的高度来完成。

<强>更新

 root
 / \
L   R

在树中,直径通过根节点,或者完全在子树之一中。有了这个:

root.diameter = max(L.height + R.height + 2, L.diameter, R.diameter)

如果我们削减一些优势,例如NN.L之间的边缘:

  root
  /  \
 ...  ...
  |
  N
 / \
L   R

L子树具有上部公式的直径。其余的树有直径

max(R.height + length(R, root) + root.height, root.R.diameter, R.diameter)

条款R.heightR.diameter取决于我们要检查的优势。当我们检查root.height子树(和反之)的边缘时,术语root.R.diameterroot.L是静态的。术语length(R, root)取决于根的边缘深度,这很容易跟踪。

使用它可以创建递归检查一个子树边上的剪切的方法。