Given an undirected tree, return its diameter: the number of edges in a longest path in that tree.
The tree is given as an array of edges where edges[i] = [u, v] is a bidirectional edge between nodes u and v. Each node has labels in the set {0, 1, ..., edges.length}.
Example 1:
Input: edges = [[0,1],[0,2]]
Output: 2
Explanation:
A longest path of the tree is the path 1 - 0 - 2.
Example 2:
Input: edges = [[0,1],[1,2],[2,3],[1,4],[4,5]]
Output: 4
Explanation:
A longest path of the tree is the path 3 - 2 - 1 - 4 - 5.
Constraints:
0 <= edges.length < 10^4
edges[i][0] != edges[i][1]
0 <= edges[i][j] <= edges.length
The given edges form an undirected tree.
class Solution {
public int treeDiameter(int[][] edges) {
if (edges == null || edges.length == 0 || edges[0].length == 0) {
return 0;
}
int n = edges.length + 1;
int[] indegree = new int[n];
GraphNode[] graph = new GraphNode[n];
for (int i = 0; i < n; i++) {
graph[i] = new GraphNode(i);
}
for (int[] edge : edges) {
int from = edge[0];
int to = edge[1];
graph[from].children.add(graph[to]);
graph[to].children.add(graph[from]);
indegree[to]++;
indegree[from]++;
}
Set<GraphNode> leaves = new HashSet<>();
for (int i = 0; i < n; i++) {
if (indegree[i] == 1) {
leaves.add(graph[i]);
}
}
// [distance, nodeNumber]
int[] oneNode = bfs(0, graph);
int[] theOtherNode = bfs(oneNode[1], graph);
return theOtherNode[0];
}
private int[] bfs(int start, GraphNode[] graph) {
int n = graph.length;
boolean[] visited = new boolean[n];
Queue<GraphNode> queue = new LinkedList<>();
queue.offer(graph[start]);
visited[start] = true;
int level = 0;
int lastNode = start;
int longestDis = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
GraphNode cur = queue.poll();
if (cur.children.size() == 1) {
lastNode = cur.val;
longestDis = level;
}
for (GraphNode nei : cur.children) {
if (!visited[nei.val]) {
queue.offer(nei);
visited[nei.val] = true;
}
}
}
level++;
}
return new int[] {longestDis, lastNode};
}
}
class GraphNode {
List<GraphNode> children = new ArrayList<>();
int val;
public GraphNode(int val) {
this.val = val;
}
public String toString() {
return String.valueOf(val);
}
}