问题描述
|
这是“平衡法”问题,要求找到树中具有最小平衡的节点。余额定义为:
删除任何节点
从树中产生的森林是:一棵或多棵树的集合。将节点的余额定义为通过从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的余额为两个。
您可以针对该问题提供哪种算法?
谢谢
解决方法
我将假设您对这个问题有全面的了解:阅读解决方案无济于事,您只能通过自己解决这些问题来更好地解决这些问题。
因此要观察的一件事是,输入是一棵树。这意味着每个边缘将2棵较小的树连接在一起。移除边缘会产生2棵不连贯的树木(2棵树木的森林)。
因此,如果您先计算边缘的一侧的树的大小,然后再计算另一侧的树的大小,则应该能够查看节点的边缘并询问\“另一侧的树的大小是多少此边缘的一面?\“
您可以使用动态编程来计算树的大小-您的重复状态为“我在哪条边上?我在哪条边上?”,它计算该节点上树“挂”的大小。 。这就是问题的症结所在。
有了这些数据,就足以遍历所有节点,查看它们的边缘并询问“该边缘另一侧的树的大小是多少?”,然后从那里选择最小值。
希望能有所帮助。
,您基本上想为每个节点检查3件事:
其左子树的大小。
其右侧子树的大小。
其余树的大小。 (树的大小-左-右)
您可以使用此算法并将其扩展到任何类型的树(不同数量的子节点)。
按顺序遍历树。
递归执行此操作:
每次从节点备份到“父亲”节点之前,都需要将节点的总子树的1+大小添加到“父亲”节点。
然后在一个节点中存储一个值,将其称为maxTree,该节点拥有其所有子树之间的最大值,以及(所有子树的总和)-(树的大小)。
这样,您可以计算O(N)中的所有子树大小。
遍历树时,可以保留一个变量,该变量保留到目前为止找到的最小值。