您已获得一个由N个节点组成的树。树是由N个节点和N-1个边组成的完全连接的图。此树中的节点从1到N编制索引。请将节点索引1视为此树的根节点。根节点位于树中的第一级。您将获得树和单个整数x。您需要找出位于x级的节点数。
输入格式
第一行由一个整数N组成,表示树中的节点数。接下来的n-1行中的每一行由2个整数a和b组成,表示节点a和节点b之间的无向边。下一行包含一个整数x。
输出格式
您需要打印一个整数,表示级别x上的节点数。
下面的是我写的代码片段,它不正确。请帮我找到错误。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
public class LevelNodes {
public static ArrayList[] adj;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
boolean[] visites = new boolean[N];
ArrayList[] adj = new ArrayList[N];
for(int j=0;j<N;j++){
adj[j] = new ArrayList();
}
for(int i = 0;i < (N-1) ;i++){
int a = sc.nextInt();
int b = sc.nextInt();
adj[a-1].add(b);
adj[b-1].add(a);
}
int level = sc.nextInt();
int counter = 0;
LinkedList list = new LinkedList();
list.add(1);
counter++;
while(!list.isEmpty()){
int n = (Integer) list.poll();
for(int x = 0; x< adj[n-1].size();x++){
list.add(adj[n-1].get(x));
}
counter++;
if(counter == level){
System.out.println(list.size());
break;
}
}
}
}
答案 0 :(得分:0)
您的代码中存在许多问题:
第一个问题是您的代码可能无法终止。这是因为您将两个边u-&gt; v和v-> u添加到邻接列表中。因此,无论何时从列表中轮询u并添加其邻居,您都要将v添加到列表中。同样,无论何时轮询v并添加其邻居,您都要将u添加回列表。只要将u添加到列表中,就需要维护一个布尔数组visited
并设置visited[u]=true
。这样,您只能将未访问的节点添加到扫描列表中。
另一个主要问题是在while循环中。每当您访问新节点时,您都在递增级别计数器变量counter++;
。考虑下面的树,并假设我们需要找到级别2(最后一级)的节点数。
1
/ \
2 3
/ \ / \
4 5 6 7
最初,您的列表包含1和counter=1
。在第一次迭代中,您从列表中轮询1并添加其邻居:2和3.在此阶段,counter=2
。在接下来的两次迭代中,您将从列表中删除2和3,添加它们的邻居,并每次递增counter
。所以到达第二级时,counter
将等于4.If语句永远不会被执行。
要解决此问题,如果您已完成处理当前级别的所有节点,则必须递增counter
。一种简单(未经测试)的方法是使用第二个临时列表来保存当前级别的所有节点的邻居。然后,只要原始列表为空,您就知道已经处理了当前级别的所有节点。在这里,您递增counter
并将所有节点从临时列表移动到主列表。
while(!list.isEmpty()){
int n = (Integer) list.poll();
for(int x = 0; x< adj[n-1].size();x++){
tmpList.add(adj[n-1].get(x));
}
if(list.isEmpty()) {
if(counter == level){
System.out.println(tmpList.size());
break;
}
list.addAll(tmpList);
tmpList.clear();
counter++;
}
}