PAT练习题(甲级) 1004 Counting Leaves (30分)(Java实现)

PAT练习题 1004 Counting Leaves(Java)

题目

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);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45062103/article/details/105973102
今日推荐