PAT 1004 Counting leaves 哈希数组与dfs

1004


1. 数组散列操作

第一次尝试:

用兄弟树来做: 记录孩子与兄弟, 发现没办法记录层数

第二次尝试

因为只需要知道孩子结点是否存在即可, flag = 0表示不是叶子结点, level是当前层数
用数组来做, 数据结构

typedef struct Node{
    int flag;
    int level;
}Node;

关键代码:

每读取一行, 判断该结点是否已经存在, 若存在, level = 该行第一个元素(其父亲)的level+1  //错误点, 父亲的level不可知

错误原因: 以为m行, 每一行的level是递增的, 实际上有可能是乱序的.

第三次尝试

参考了
https://blog.csdn.net/IAccepted/article/details/21289205
修改:

  1. 读取时仅仅只保存该结点父亲结点;
  2. 根据保存的父亲结点关系, 已知根节点的编号,
    用双重循环来确定该结点在第几层 用双重循环来确定该结点在第几层
    第一次循环寻找根节点的孩子, 并修改孩子的层数为2
    第二次循环寻找父亲层数为2 的孩子 修改孩子层数为3,
#include <stdio.h>
#include <stdlib.h>


typedef struct Node{
    int flag;
    int father;
    int level;
}Node;


int main()
{
    int i,j, n,m;
    scanf("%d %d", &n, &m);
    Node nodes[105];
    int ans[105];

    for(i = 0; i < 105; i++){
        nodes[i].flag = 0;
        nodes[i].level = 0;
        ans[i] = 0;
        nodes[i].father = 0;
    }
    int maxLevel = 0;
    nodes[1].level = 1;
    for(i = 0; i < m && i < n; i++){
        int k, id;
        scanf("%d %d", &id, &k);
        nodes[id].flag = 1;
        for(j = 0; j < k; j++){
            int child_id;
            scanf("%d", &child_id);
            nodes[child_id].father = id;
        }
    }

    for(i = 1; i < 102; i++){
        for(j = 1; j < 102; j++){
            if (nodes[j].father == i){
                nodes[j].level = nodes[i].level+1;
                if(nodes[j].level>maxLevel){
                    maxLevel = nodes[j].level;
                }
            }
        }
    }

    for(i = 1; i < 102; i++)
    {
        if(nodes[i].flag == 0){
            ans[nodes[i].level]++;
        }
    }

    printf("%d", ans[1]);
    for(i = 2; i <= maxLevel; i++){
        printf(" %d", ans[i]);
    }

    return 0;
}

突然发现新的方法~ 这不就是我第一次的想法吗

参考文章
https://blog.csdn.net/IAccepted/article/details/21289205#commentBox

2.1.想法:

只要在每一行第一个数出现过的, 必然不是叶子结点
数据结构: HashMap<Integer, List<Integer>>, key为每一行第一个数, value为它的孩子结点

2.2. 难点

我一开始放弃这个想法就是因为没办法确定没有孩子结点的层数.
然而, 确定孩子结点的层数, 必须抓住root(01)的level是已知的!!!

2.3 代码

package countleaves1004;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Main {
	static Map<Integer, List<Integer>> adjlist = new HashMap<>();
	static int[] record = new int[200];
	
	public static void dfs(int level,int id){
		if(!adjlist.containsKey(id)){  //说明该结点无孩子
			++record[level];
			return;
		}
		for(int i: adjlist.get(id)){
			dfs(level+1, i);
		}
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int nlf = n-m;
		while(m-- > 0){
			int id = sc.nextInt();
			int k = sc.nextInt();
			adjlist.put(id, new ArrayList<Integer>());
			while(k-- > 0){
				int sid = sc.nextInt();
				adjlist.get(id).add(sid);
			}
		}
		dfs(0, 1);
		int cln = record[0];
		System.out.printf("%d", record[0]);
		for(int i = 1; cln < nlf; i++){
			System.out.printf(" %d", record[i]);
			cln += record[i];
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_40978095/article/details/82793770