Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在没有动态规划的情况下,在线性时间内获取树中每个节点的子体数?_Java_Algorithm_Tree - Fatal编程技术网

Java 在没有动态规划的情况下,在线性时间内获取树中每个节点的子体数?

Java 在没有动态规划的情况下,在线性时间内获取树中每个节点的子体数?,java,algorithm,tree,Java,Algorithm,Tree,我编写了一个递归函数,用于计算n元树中每个节点的子代数。 计算结果在传入的数组中。我正在寻找一个函数,在线性时间运行,不使用动态规划。理想情况下,结果将在每个节点内设置,而不需要单独的数据结构。如果可能,首选递归 void setNumberDescendants(Node root, int[] descCount) { for(Node child:root.children){ setNu

我编写了一个递归函数,用于计算n元树中每个节点的子代数。 计算结果在传入的数组中。我正在寻找一个函数,在线性时间运行,不使用动态规划。理想情况下,结果将在每个节点内设置,而不需要单独的数据结构。如果可能,首选递归

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。