题解 | #多叉树的直径#

多叉树的直径

https://www.nowcoder.com/practice/a77b4f3d84bf4a7891519ffee9376df3

思路参见
需要注意的地方:
1. 题目给的是多叉树,所以求经过当前根结点的最大路径时,需要选择两个收益最大的子树,其和则为结果
2. 图的数据结构选择:最开始用的邻接矩阵,爆堆了。后采用双层map,可通过所有用例。
import java.util.*;

public class Solution {
    /**
     * 树的直径
     *
     * @param n int整型 树的节点个数
     * @param Tree_edge Interval类一维数组 树的边
     * @param Edge_value int整型一维数组 边的权值
     * @param maxSum 记录当前最大路径
     * @param visited 记录图遍历过的结点
     * @return int整型
     */
    int maxSum;
    int[] visited;

    public int solve(int n, ArrayList<Interval> Tree_edge, ArrayList<Integer> Edge_value) {
        // write code here
        maxSum = 0;
        visited = new int[n];
        // 将多叉树转换为有权无向图,存放在双层map
        Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();
        for (int i = 0; i < Tree_edge.size(); i++) {
            Map<Integer, Integer> child1 = graph.getOrDefault(Tree_edge.get(i).start, new HashMap<>());
            child1.put(Tree_edge.get(i).end, Edge_value.get(i));
            graph.put(Tree_edge.get(i).start, child1);
            Map<Integer, Integer> child2 = graph.getOrDefault(Tree_edge.get(i).start, new HashMap<>());
            child2.put(Tree_edge.get(i).end, Edge_value.get(i));
            graph.put(Tree_edge.get(i).end, child2);
        }
        // 既然是树结构,无论从以哪个结点作为根结点并从其出发,都可以遍历到所有结点
        maxGain(graph, 0);
        return maxSum;
    }

    /***
     *
     * @param graph
     * @param root 根结点的序号
     * @return 经过root的最大路径
     */
    public int maxGain(Map<Integer, Map<Integer, Integer>> graph, int root) {
        visited[root] = 1;
        int maxChildGain = 0;
        int secondMaxChildGain = 0;
        Map<Integer, Integer> childMap = graph.get(root);
        if (childMap == null || childMap.size() == 0) {
            return 0;
        }
        int child, path;
        for (Map.Entry<Integer, Integer> kv : childMap.entrySet()) {
            child = kv.getKey();
            path = kv.getValue();
            path += maxGain(graph, child);
            if (path > maxChildGain) {
                secondMaxChildGain = maxChildGain;
                maxChildGain = path;
            } else if (path > secondMaxChildGain) {
                secondMaxChildGain = path;
            }
        }
        /**
         * 题目中所求的最大路径,必然会经过某个子树的根结点。
         * 所以在遍历过程中,对于每个结点,都求一次以该结点为根的子树,经过根结点的最大路径
         * 与maxSum进行对比即可求出最大路径
         */
        maxSum = Math.max(maxSum, maxChildGain + secondMaxChildGain);
        visited[root] = 0;
        return maxChildGain;
    }
}


全部评论

相关推荐

06-19 14:58
门头沟学院 Java
点赞 评论 收藏
分享
深夜书店vv:腾讯是这样的,去年很多走廊都加桌子当工区
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务