题目
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 0<N<100, the number of nodes in a tree, and M (<N), the number of non-leaf nodes. Then M lines follow, each in the format:
ID K ID[1] ID[2] … ID[K]
where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 01.
The input ends with N being 0. That case must NOT be processed.
Output Specification:
For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.
The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.
Sample Input:
2 1
01 1 02
Sample Output:
0 1
题意
- 第一行输入两个值,N是这个树中的所有结点数,M是这个树里的非叶子结点数
- 下面的M行是输入子树,ID是子树的根结点,K是根结点的孩子结点,随后输入K个结点
- 输出的是树的每一层的叶子结点
- 叶子结点指的是在这个结点下没有孩子结点
解题思路
- 首先就是利用循环进行输入,在这里我是用的是HashMap,主要是为了组建一棵遍历快的树,节省时间
- 因为是按照层数的叶子结点数进行输出,所以使用深度优先遍历这棵树会更方便
- 最后使用存储每一层叶子结点数的数组进行输出,在构思的时候要灵活利用数组的索引,将数组的索引看作层数,然后进行对应存储,同时数组的默认值是0,可以利用这两个特点进行使用
- 答题的时候保持逻辑清晰就行了,想清楚了就不难
代码实现
import java.util.HashMap;
import java.util.Scanner;
public class Test {
static Scanner sc = new Scanner(System.in);
static int n = sc.nextInt();//树中共有n个结点
static int m = sc.nextInt();//树中共有m个非叶子结点
static HashMap<Integer,int[]> tree = new HashMap<>();//用于组建树
static int[] leafnum = new int[100];//每层叶子结点数的数组,该数组的索引就是代表第几层
public static void main(String[] args)
{
//双重循环用于把数据存到树中
for(int i = 0;i<m;i++) {
int nodenum = sc.nextInt();//nodenum是子树根结点的编号
int k = sc.nextInt();//k是这个子树的孩子结点
int[] nodes = new int[k];
for (int j = 0; j < k; j++) {
int id = sc.nextInt();
nodes[j] = id;
}
tree.put(nodenum, nodes);
}
DFS(1,0);//深度遍历,此处使用迭代实现,代码在下面
int sum = 0;//sum是计算树的所有结点数
int num = 0;//用于记录有多少个子树
for(int i = 0;i<leafnum.length;i++)
{
int j = leafnum[i];
sum += j;
if(sum == n-m)
{
num = i;
break;
}
}
//使用for循环打印leafnum数组
for(int i = 0;i<=num;i++)
{
if(i != num)
System.out.print(leafnum[i]+" ");
else
System.out.println(leafnum[i]);
}
}
//深度优先遍历(递归实现)
public static void DFS(int node,int deep)
{
if(!tree.containsKey(node))//通过判断树中是否存在以node为根结点的子树
{
leafnum[deep]++;
return;
}
else {
int[] list = tree.get(node);
for (int i = list[0]; i <= list[list.length - 1]; i++) {
DFS(i, deep + 1);
}
}
}
}