题目链接:https://leetcode-cn.com/contest/biweekly-contest-12/problems/tree-diameter/
给你这棵「无向树」,请你测算并返回它的「直径」:这棵树上最长简单路径的 边数。
我们用一个由所有「边」组成的数组 edges
来表示一棵无向树,其中 edges[i] = [u, v]
表示节点 u
和 v
之间的双向边。
树上的节点都已经用 {0, 1, ..., edges.length}
中的数做了标记,每个节点上的标记都是独一无二的。
示例 1:
输入:edges = [[0,1],[0,2]]
输出:2
解释:这棵树上最长的路径是 1 - 0 - 2,边数为 2。
示例 2:
输入:edges = [[0,1],[1,2],[2,3],[1,4],[4,5]]
输出:4
解释:这棵树上最长的路径是 3 - 2 - 1 - 4 - 5,边数为 4。
提示:
0 <= edges.length < 10^4
edges[i][0] != edges[i][1]
0 <= edges[i][j] <= edges.length
edges
会形成一棵无向树
题解
采用 邻接表 的存储结构保存树的信息。
深度优先搜索所有端点。最长的就是最终的结果。
Java代码
/**
* Author:wowpH
* ID :pfdvnah
* Date :2019年11月5日19:28:35
* From :https://blog.csdn.net/pfdvnah/article/details/102922383
*/
class Solution {
public int treeDiameter(int[][] edges) {
int n = edges.length + 1;// 结点数
// 用邻接表的存储结构保存树的信息
List<List<Integer>> tree = new ArrayList<>();
for (int i = 0; i < n; ++i) {
tree.add(new ArrayList<>());
}
// 根据边的信息生成邻接表
for (int[] edge : edges) {
tree.get(edge[0]).add(edge[1]);
tree.get(edge[1]).add(edge[0]);
}
int ret = 0;
for (int i = 0; i < n; ++i) {
// 最长的路径的端点的度一定为1,这样能去掉不必要的DFS
if (tree.get(i).size() == 1) {
ret = Math.max(ret, dfs(tree, -1, i));
}
}
return ret - 1;// 题目问的是直径(边数),所以要减1
}
// 返回最大结点数。@wowpH
private int dfs(List<List<Integer>> tree,
int pre,// 前驱点
int cur) {// 当前点
int ret = 0;
List<Integer> list = tree.get(cur);// 与当前结点相连的结点
for (int i = 0; i < list.size(); ++i) {
int next = list.get(i);
if (next != pre) {// 不是前驱结点,下一层DFS
ret = Math.max(ret, dfs(tree, cur, next));
}
}
return ret + 1;// 加上当前结点
}
}
原文链接:https://blog.csdn.net/pfdvnah/article/details/102922383