PAT 1004 Counting Leaves (30分) BFS找每一层非叶子节点数

题目

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

思路分析

• 不用构建树的结构体，首先我们不用区分孩子的顺序，知道它有几个孩子，编号是几就可以了；其次，每个非叶子节点所拥有的孩子数目是不一样的，也无法构建结构体。
• 所以，我们用一个`vector数组`，每个`vector`保存一个非叶子节点的所有孩子编号。
• 判断是否是叶子节点很简单，只需要判断它对应的vector的size是否为0就可以。
• 由于我们不能直接确定树的结构，而最后输出每一层的非叶子节点个数，所以需要一个变量`maxLevel`保存这个数有多高，也就是最深一层是哪一层。
• 然后我们要求得每一层的叶子节点有几个，所以还得用一个`数组`保存每一层的叶子节点数。
• 接下来，从`根节点`开始，进行递归就好了
```	// 根节点编号是1，层级是0
helper(1, 0);
// index 节点编号； level 节点在哪一层
void helper(int index, int level) {
// 他没有孩子，它是叶子节点，
if (nodes[index].size() == 0) {
// 他所在这一层叶子节点数+1
levelLeaves[level]++;
// 更新 这棵树的最深的有效层
maxLevel = max(maxLevel, level);
return;
}
// 他的所有孩子都处于他的下一层
for (int i = 0; i < nodes[index].size(); ++i)
helper(nodes[index][i], level + 1);
}
} ```

完整代码

```#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 保存每个节点的全部孩子，自己的编号作为下标，值是一个vector
vector<int> nodes[100];
// 保存每一层有几个叶子节点
int levelLeaves[100];
// 题目最多有100个节点，保存最深的有效层是哪一层

int maxLevel = -1;

//
void helper(int index, int level) {
// 他没有孩子，他所在这一层叶子节点数+1
if (nodes[index].size() == 0) {
levelLeaves[level]++;
// 更新 最深的有效层
maxLevel = max(maxLevel, level);
return;
}
// 他的所有孩子都处于他的下一层
for (int i = 0; i < nodes[index].size(); ++i)
helper(nodes[index][i], level + 1);
}

int main() {

// n个节点，m个非叶子节点
int n, m;

int index, kids, child;

cin >> n >> m;

// 每一行是一个非叶子节点的情况
// 编号 几个孩子 孩子1编号 孩子2编号 ...
for (int i = 0; i < m; ++i) {
cin >> index >> kids;
for (int j = 0; j < kids; ++j) {
cin >> child;
nodes[index].push_back(child);
}
}

// 根节点编号是1，层级是0
helper(1, 0);

// 这样写会导致最终多出来一个空格，不满足输出要求
//	for (int i = 0; i < maxLevel; ++i)
//		cout << levelLeaves[i] << " ";
// 输出每一层的叶子节点个数
cout << levelLeaves[0];
// maxLevel是最深层
for (int i = 1; i <= maxLevel; ++i)
cout << " " << levelLeaves[i];

return 0;
}```

0 条评论

• PAT 1021 Deepest Root (25分) 从测试点3超时到满分再到代码优化

A graph which is connected and acyclic can be considered a tree. The height of t...

• 最通俗易懂入门红黑树(R-B Tree)

二叉平衡树(AVL)：二叉平衡树是在二叉搜素树的基础上加上了限制：任意节点，左右子树的高度差不能超过1。这个约束常常借助左旋和右旋操作实现。

• PAT 1052 Linked List Sorting (25分) 结构体排序而已

A linked list consists of a series of structures, which are not necessarily adja...

• Raft分布式一致性算法整理 顶 原

CAP定理指出，在异步网络模型中，不存在一个系统可以同时满足上述3个属性。换句话说，分布式系统必须舍弃其中的一个属性。对于需要在分布式条件下运行的系统来说，如何...

• 重温数据结构：理解 B 树、B+ 树特点及使用场景

B 树就是常说的“B 减树（B- 树）”，又名平衡多路（即不止两个子树）查找树，它和平衡二叉树的不同有这么几点：

• 力扣207——课程表

在选修某些课程之前需要一些先修课程。例如，想要学习课程 0 ，你需要先完成课程 1 ，我们用一个匹配来表示他们: [0,1]

• 5.4删除二叉搜索树的任意元素

节点删除之后，将左孩子所在的二叉树取代其位置；连在原来节点父亲元素右节点的位置，比如在图中需要删除58这个节点。

• Python 刷题笔记：深度优先搜索专题

今天来接触下专业术语——深度优先搜索算法（英语：Depth-First-Search，DFS）

• LeetCode Contest 177

给你一些点和边，判断是否是一颗二叉树。只需要判断所有点的入度<=1 ，并且入度为0的点只有一个，就可以了。

• Leetcode 164 Maximum Gap 桶排序好题

Given an unsorted array, find the maximum difference between the successive ele...