题解 | #多叉树的直径#
多叉树的直径
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; } }