这是Balancing Act问题,需要找到树中具有最小余额的节点。余额定义为:
删除任何节点 从树中产生一个森林:一个或多个树的集合。将节点的 balance 定义为通过从T
删除该节点而创建的林T中最大树的大小
对于样本树,例如:
2 6
1 2
1 4
4 5
3 7
3 1
说明是:
删除节点4会生成两个树,其成员节点为{5}和{1,2,3,6,7}。该 这两棵树中较大的一个有五个节点,因此节点4的余额为五。删除节点 1产生一个相同大小的三棵树的森林:{2,6},{3,7}和{4,5}。这些树中的每一个 有两个节点,所以节点1的余额是两个。
你可以为这个问题提供什么样的算法?
由于
答案 0 :(得分:1)
我将假设您已经对这个问题进行了宽松的观察:阅读解决方案并没有帮助,只有通过解决这些问题才能更好地解决这些问题自己。
所以需要注意的一点是,输入是一棵树。这意味着每条边将2棵较小的树连在一起。删除边缘会产生2个断开连接的树(2棵树林)。
因此,如果您计算边缘一侧树的大小,然后另一侧计算树的大小,您应该能够查看节点的边缘并询问“另一侧树的大小是多少”这边缘?“
你可以使用动态编程来计算树木的大小 - 你的重现状态是“我在哪个边缘?我的边缘的哪一边?”并计算该节点“挂”树的大小。这就是问题的症结所在。
拥有这些数据后,遍历所有节点就足够了,看看它们的边缘并询问“这条边的另一边树的大小是多少?”从那里,你只需选择最低限度。
希望有所帮助。
答案 1 :(得分:0)
您基本上想要检查每个节点的3件事情:
您可以使用此算法将其扩展为任何类型的树(不同数量的子节点)。
在in-order sequence中浏览树。
递归地执行此操作:
每次从节点备份到“父”节点之前,需要将1 +大小的节点总子树添加到“父”节点。
然后存储一个值,我们称之为 maxTree ,在所有子树之间保持最大值的节点和(所有子树的总和) - (树的大小)。
这样您就可以在 O(N) 中计算所有子树大小。
在遍历树时,您可以保存一个包含到目前为止找到的最小值的变量。