class Tree {
adjacencyList: Map<number, number[]> = new Map();
addEdge(u: number, v: number) {
if (!this.adjacencyList.has(u)) this.adjacencyList.set(u, []);
if (!this.adjacencyList.has(v)) this.adjacencyList.set(v, []);
this.adjacencyList.get(u)!.push(v);
this.adjacencyList.get(v)!.push(u);
}
diameter(): number {
let diameter = 0;
const visited = new Set<number>();
const dfs = (node: number): number => {
visited.add(node);
let max1 = 0, max2 = 0;
for (const neighbor of this.adjacencyList.get(node) || []) {
if (!visited.has(neighbor)) {
const length = dfs(neighbor) + 1;
if (length > max1) {
max2 = max1;
max1 = length;
} else if (length > max2) {
max2 = length;
}
}
}
diameter = Math.max(diameter, max1 + max2);
return max1;
};
dfs(1);
return diameter;
}
}
// Driver code
const tree = new Tree();
tree.addEdge(1, 2);
tree.addEdge(1, 3);
tree.addEdge(2, 4);
tree.addEdge(3, 5);
console.log(tree.diameter());const dfs = (node: number): number => {
start DFS to explore longest downward paths from node
mark node as visited to avoid cycles
for (const neighbor of this.adjacencyList.get(node) || []) {
iterate over neighbors to explore subtrees
if (!visited.has(neighbor)) {
only visit unvisited neighbors to prevent revisiting
const length = dfs(neighbor) + 1;
compute longest path length from neighbor plus edge
if (length > max1) { max2 = max1; max1 = length; } else if (length > max2) { max2 = length; }
track top two longest downward paths from children
diameter = Math.max(diameter, max1 + max2);
update diameter with sum of two longest paths through current node
return longest downward path for parent's calculation