Java 在没有动态规划的情况下,在线性时间内获取树中每个节点的子体数?
我编写了一个递归函数,用于计算n元树中每个节点的子代数。 计算结果在传入的数组中。我正在寻找一个函数,在线性时间运行,不使用动态规划。理想情况下,结果将在每个节点内设置,而不需要单独的数据结构。如果可能,首选递归Java 在没有动态规划的情况下,在线性时间内获取树中每个节点的子体数?,java,algorithm,tree,Java,Algorithm,Tree,我编写了一个递归函数,用于计算n元树中每个节点的子代数。 计算结果在传入的数组中。我正在寻找一个函数,在线性时间运行,不使用动态规划。理想情况下,结果将在每个节点内设置,而不需要单独的数据结构。如果可能,首选递归 void setNumberDescendants(Node root, int[] descCount) { for(Node child:root.children){ setNu
void setNumberDescendants(Node root, int[] descCount) {
for(Node child:root.children){
setNumberDescendants(child, descCount);
descCount[root.key] += 1+descCount[child.key];
}
}
class Node{
int key;
List<Node> children;
}
void setNumberDescendants(节点根,int[]descCount){
for(节点子节点:root.children){
setNumberDescendants(子项,递减计数);
descCount[root.key]+=1+descCount[child.key];
}
}
类节点{
int键;
列出儿童名单;
}
您的解决方案满足您的要求
它是线性的:您只访问每个节点一次,并为每个节点执行恒定的工作量
它不使用动态规划:动态规划要求问题显示重叠子问题和最优子结构。此问题不显示重叠的子问题。对于集合节点,子问题由该节点上的子树的答案组成。这些子树没有重叠
如果要在每个节点中设置结果,只需执行以下操作:
void setNumberDescendants(Node root) {
for(Node child:root.children){
setNumberDescendants(child);
root.descendants += 1+child.descendants;
}
}
class Node{
int key;
int descendants;
List<Node> children;
}
void setNumberDescendants(节点根){
for(节点子节点:root.children){
SetNumberDescents(儿童);
root.subscriptions+=1+子.subscriptions;
}
}
类节点{
int键;
int后代;
列出儿童名单;
}
您自己的解决方案正是这样做的。我误解了“重叠子问题”。我原以为这意味着任何子问题都会重叠,但如果必须是“对于集合节点”,我理解我的错误。@lf215-您可以这样想:如果解决方案的直接递归实现会多次计算同一事物,该问题显示出重叠的子问题,否则它不会。例如,以斐波那契为例:f(n)=f(n-1)+f(n-2)
。如果直接实现这个递归,f(n)
将计算f(n-2)
,然后f(n-1)
将计算f(n-1-1)=f(n-2)
,这是相同的事情。这里有重叠的子问题。在你的情况下,这种情况不会发生。是的,我会在你发布答案并理解后立即阅读。我的错误是因为我认为最初的“问题”是计算每个节点的子代数。(通过向下遍历每个节点的树,朴素的impl可能是n^2。)如果这是问题所在,那么2个子问题可能是计算根的后代和计算差异节点“x”的后代。因此,这两个子问题必然重叠。但我的“问题”实际上是计算给定节点上的后代,由于解决方案的递归impl,它最终计算每个节点上的desc。