Diameter of a Graph Without Cycles

Last Updated : 28 Oct, 2025

Given an undirected graph(with no cycles) represented using an adjacency list adj[][], find the diameter of the graph.
The diameter of a graph (sometimes called the width) is the number of edges on the longest path between two nodes in the graph.

Note: Graph do not contain any disconnected component.

Examples:

Input: adj[][] = [[1], [0, 2], [1, 3], [2, 4], [3]]

frame_3150

Output: 4
Example: The diameter of the graph is a path between 0 and 4 containing edges {0, 1}, {1, 2}, {2, 3}, {3, 4}.

Input: adj[][] = [[1, 2, 3], [0, 4], [0, 5], [0], [1], [2]]

420046870

Output: 4
Example: The diameter of the tree is a path between 4 and 5 containing edges {4, 1}, {1, 0}, {0, 2}, {2, 5}.

Try It Yourself
redirect icon

[Approach - 1] Finding farthest node from each node - O(n2) Time and O(n) Space

This approach considers every node as a starting point and finds its farthest reachable node. This way, we cover all possibilities of taking each node as the endpoint of the diameter.

C++
//Driver Code Starts
#include <vector>
#include <iostream>
using namespace std;

//Driver Code Ends

int farthestNode(int curr, vector<bool>& visited, vector<vector<int>>& adj, int dist) {
    if (visited[curr]) return 0;

    visited[curr] = true;
    int maxDist = dist;

    for (int next : adj[curr]) {
        // visiting the next node 
        // if not visited already
        if (!visited[next]) {
            maxDist = max(maxDist, farthestNode(next, visited, adj, dist + 1));
        }
    }
    return maxDist;
}

int diameter(vector<vector<int>>& adj) {
    int n = adj.size();
    int res = 0;

    // taking maximum across all nodes
    for (int i = 0; i < n; i++) {
        vector<bool> visited(n, false);
        res = max(res, farthestNode(i, visited, adj, 0));
    }
    return res;
}

//Driver Code Starts

void addEdge(vector<vector<int>>& adj, int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}


int main() {
    int V = 5;
    vector<vector<int>> adj(V);
    
    // creating adjacency list
    addEdge(adj, 0, 1);
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 3, 4);

    int res = diameter(adj);
    cout << res << endl;
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;

class GFG {
//Driver Code Ends

    static int diameter(ArrayList<ArrayList<Integer>> adj) {
        int n = adj.size();
        int res = 0;
        // taking maximum across all nodes
        for( int i = 0; i < n; i++ ) {
            boolean[] visited = new boolean[n];
            res = Math.max(res, 
            farthestNode(i, visited, adj, 0));
        }
        return res;

    }
    static int farthestNode( int curr, boolean[] visited, ArrayList<ArrayList<Integer>> adj, int dist){
        if( visited[curr]) return 0;
    
        visited[curr] = true;
        int maxDist = dist;

        for( int next : adj.get(curr)) {
            // visiting the next node 
            // if not visited already
            if(!visited[next]) {
                maxDist = Math.max(maxDist, farthestNode(next, visited, adj, dist+1));
            }
        }
        return maxDist;
    }

//Driver Code Starts
    static void addEdge(ArrayList<ArrayList<Integer>> adj, int u, int v) {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }

    public static void main(String[] args) {
        int V = 5;
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.add(new ArrayList<>());

        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);
        
        int res = diameter(adj);
        System.out.println(res);
    }
}
//Driver Code Ends
Python
def farthestNode(curr, visited, adj, dist):
    if visited[curr]:
        return 0

    visited[curr] = True
    maxDist = dist

    for next_node in adj[curr]:
        # visiting the next node 
        # if not visited already
        if not visited[next_node]:
            maxDist = max(maxDist, farthestNode(next_node, visited, adj, dist + 1))
    return maxDist

def diameter(adj):
    n = len(adj)
    res = 0

    # taking maximum across all nodes
    for i in range(n):
        visited = [False] * n
        res = max(res, farthestNode(i, visited, adj, 0))
    return res


#Driver Code Starts
def addEdge(adj, u, v):
    adj[u].append(v)
    adj[v].append(u)
    
    
if __name__ == "__main__":
    V = 5
    adj = []
    
    # creating adjacency list
    for i in range(V):
        adj.append([])
        
    addEdge(adj, 0, 1)
    addEdge(adj, 1, 2)
    addEdge(adj, 2, 3)
    addEdge(adj, 3, 4)
    
    res = diameter(adj)
    print(res)

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG {
//Driver Code Ends

    static int farthestNode(int curr, bool[] visited, List<List<int>> adj, int dist) {
        if (visited[curr]) return 0;

        visited[curr] = true;
        int maxDist = dist;

        foreach (int next in adj[curr]) {
            // visiting the next node 
            // if not visited already
            if (!visited[next]) {
                maxDist = Math.Max(maxDist, farthestNode(next, visited, adj, dist + 1));
            }
        }
        return maxDist;
    }

    static int diameter(List<List<int>> adj) {
        int n = adj.Count;
        int res = 0;

        // taking maximum across all nodes
        for (int i = 0; i < n; i++) {
            bool[] visited = new bool[n];
            res = Math.Max(res, farthestNode(i, visited, adj, 0));
        }
        return res;
    }

//Driver Code Starts

    static void addEdge(List<List<int>> adj, int u, int v) {
        adj[u].Add(v);
        adj[v].Add(u);
    }

    static void Main() {
        int V = 5;
        List<List<int>> adj = new List<List<int>>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.Add(new List<int>());
            
        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);

        int res = diameter(adj);
        Console.WriteLine(res);
    }
}
//Driver Code Ends
JavaScript
function farthestNode(curr, visited, adj, dist) {
    if (visited[curr]) return 0;

    visited[curr] = true;
    let maxDist = dist;

    for (const next of adj[curr]) {
        // visiting the next node 
        // if not visited already
        if (!visited[next]) {
            maxDist = Math.max(maxDist, farthestNode(next, visited, adj, dist + 1));
        }
    }
    return maxDist;
}

function diameter(adj) {
    const n = adj.length;
    let res = 0;

    // taking maximum across all nodes
    for (let i = 0; i < n; i++) {
        let visited = Array(n).fill(false);
        res = Math.max(res, farthestNode(i, visited, adj, 0));
    }
    return res;
}


//Driver Code Starts
function addEdge(adj, u, v) {
    adj[u].push(v);
    adj[v].push(u);
}

// Driver code

let V = 5;
let adj = [];

// creating adjacency list
for (let i = 0; i < V; i++)
    adj.push([]);

addEdge(adj, 0, 1);
addEdge(adj, 1, 2);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);

const res = diameter(adj);
console.log(res);

//Driver Code Ends

Output
4

[Expected Approach-1] Finding ends of diameter - O(n) Time and O(n) Space

In this approach, we first perform a DFS (or BFS) from any node to find the farthest node, which becomes one endpoint of the longest path. Then, starting from this farthest node, we perform another DFS to find the node farthest from it. The distance between these two nodes gives the tree’s diameter, representing the longest path between any two nodes.

Why this approach works?

This works because in a tree, the longest path (diameter) always has its endpoints as the farthest nodes from each other. When we run the first DFS from any node, we reach one endpoint of this longest path. Running the second DFS from that endpoint ensures we traverse the maximum possible distance in the tree, therefore, discovering the diameter.

C++
//Driver Code Starts
#include <vector>
#include <iostream>
using namespace std;

//Driver Code Ends

void farthestNode(int curr, vector<vector<int>>& adj, int currentDist, vector<int>& dist, vector<bool>& visited) {
    if (visited[curr]) return;
    if (dist[0] < currentDist) {
        // contains an array with index 0
        // having max dist and index 1 having
        // node at that distance from src
        dist[0] = currentDist;
        dist[1] = curr;
    }
    visited[curr] = true;
    for (int next : adj[curr]) {
        if (!visited[next]) {
            farthestNode(next, adj, currentDist + 1, dist, visited);
        }
    }
}

int diameter(vector<vector<int>>& adj) {
    int n = adj.size();
    vector<int> dist = {0, 0};
    vector<bool> visited(n + 1, false);

    // finding node at max distance from 0th node
    farthestNode(0, adj, 0, dist, visited);
    int end1 = dist[1];

    dist = {0, 0};
    // finding node at max distance 
    // from end1 of diameter
    vector<bool> visited2(n, false);
    farthestNode(end1, adj, 0, dist, visited2);
    return dist[0];
}

//Driver Code Starts

void addEdge(vector<vector<int>>& adj, int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}


int main() {
    int V = 5;
    vector<vector<int>> adj(V);
    
    // creating adjacency list
    addEdge(adj, 0, 1);
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 3, 4);

    int res = diameter(adj);
    cout << res << endl;
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;

class GFG {
//Driver Code Ends

    static int diameter(ArrayList<ArrayList<Integer>> adj) {
        int n = adj.size();
        int[] dist = new int[2];
        // finding node at max distance from 0th node
        farthestNode(0, adj, 0, dist, new boolean[n]);
        int end1 = dist[1];
        
        dist = new int[2];
        
        // finding node at max distance 
        // from end1 of diameter
        farthestNode(end1, adj, 0, dist, new boolean[n]);
        return dist[0];
    }
    static void farthestNode( int curr, ArrayList<ArrayList<Integer>> adj, int currentDist, int[] dist, boolean[] visited ){
        if( visited[curr]) return;
        if( dist[0] < currentDist ) {
            
            // contains an array with index 0
            // having max dist and index 1 having
            // node at that distance from src
            dist[0] = currentDist;
            dist[1] = curr;
        }
        visited[curr] = true;
        for( int next : adj.get(curr)) {
            if(!visited[next]) {
                farthestNode(next, adj, currentDist+1, dist, visited);
            }
        }
    }

//Driver Code Starts
    static void addEdge(ArrayList<ArrayList<Integer>> adj, int u, int v) {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }

    public static void main(String[] args) {
        int V = 5;
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.add(new ArrayList<>());

        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);
        
        int res = diameter(adj);
        System.out.println(res);
    }
}
//Driver Code Ends
Python
def farthestNode(curr, adj, currentDist, dist, visited):
    if visited[curr]:
        return
    if dist[0] < currentDist:
        # contains an array with index 0
        # having max dist and index 1 having
        # node at that distance from src
        dist[0] = currentDist
        dist[1] = curr
    visited[curr] = True
    for next_node in adj[curr]:
        if not visited[next_node]:
            farthestNode(next_node, adj, currentDist + 1, dist, visited)


def diameter(adj):
    n = len(adj) + 1
    dist = [0, 0]
    # finding node at max distance from 0th node
    farthestNode(0, adj, 0, dist, [False] * n)
    end1 = dist[1]

    dist = [0, 0]
    # finding node at max distance 
    # from end1 of diameter
    farthestNode(end1, adj, 0, dist, [False] * n)
    return dist[0]


#Driver Code Starts
def addEdge(adj, u, v):
    adj[u].append(v)
    adj[v].append(u)
    
    
if __name__ == "__main__":
    V = 5
    adj = []
    
    # creating adjacency list
    for i in range(V):
        adj.append([])
        
    addEdge(adj, 0, 1)
    addEdge(adj, 1, 2)
    addEdge(adj, 2, 3)
    addEdge(adj, 3, 4)
    
    res = diameter(adj)
    print(res)

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG {
//Driver Code Ends

    static void farthestNode(int curr, List<List<int>> adj, int currentDist, int[] dist, bool[] visited) {
        if (visited[curr]) return;
        if (dist[0] < currentDist) {
            // contains an array with index 0
            // having max dist and index 1 having
            // node at that distance from src
            dist[0] = currentDist;
            dist[1] = curr;
        }
        visited[curr] = true;
        foreach (int next in adj[curr]) {
            if (!visited[next]) {
                farthestNode(next, adj, currentDist + 1, dist, visited);
            }
        }
    }

    static int diameter(List<List<int>> adj) {
        int n = adj.Count; 
        int[] dist = new int[2];
        // finding node at max distance from 0th node
        farthestNode(0, adj, 0, dist, new bool[n + 1]);
        int end1 = dist[1];

        dist = new int[2];
        // finding node at max distance 
        // from end1 of diameter
        farthestNode(end1, adj, 0, dist, new bool[n]);
        return dist[0];
    }

//Driver Code Starts

    static void addEdge(List<List<int>> adj, int u, int v) {
        adj[u].Add(v);
        adj[v].Add(u);
    }

    static void Main() {
        int V = 5;
        List<List<int>> adj = new List<List<int>>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.Add(new List<int>());
            
        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);

        int res = diameter(adj);
        Console.WriteLine(res);
    }
}

//Driver Code Ends
JavaScript
function farthestNode(curr, adj, currentDist, dist, visited) {
    if (visited[curr]) return;
    if (dist[0] < currentDist) {
        // contains an array with index 0
        // having max dist and index 1 having
        // node at that distance from src
        dist[0] = currentDist;
        dist[1] = curr;
    }
    visited[curr] = true;
    for (const next of adj[curr]) {
        if (!visited[next]) {
            farthestNode(next, adj, currentDist + 1, dist, visited);
        }
    }
}

function diameter(adj) {
    const n = adj.length + 1;
    let dist = [0, 0];
    // finding node at max distance from 0th node
    farthestNode(0, adj, 0, dist, Array(n).fill(false));
    const end1 = dist[1];

    dist = [0, 0];
    // finding node at max distance 
    // from end1 of diameter
    farthestNode(end1, adj, 0, dist, Array(n).fill(false));
    return dist[0];
}


//Driver Code Starts
function addEdge(adj, u, v) {
    adj[u].push(v);
    adj[v].push(u);
}

// Driver code

let V = 5;
let adj = [];

// creating adjacency list
for (let i = 0; i < V; i++)
    adj.push([]);

addEdge(adj, 0, 1);
addEdge(adj, 1, 2);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);

const res = diameter(adj);
console.log(res);

//Driver Code Ends

Output
4

[Expected Approach-2] Taking each node as Meeting point- O(n) Time and O(n) Space

In this approach, we compute the diameter by considering each node as a potential meeting point of the longest path. For each node, we find the two farthest leaf nodes (in terms of distance) within its reachable subgraph. The sum of their distances (plus the two connecting edges through the current node) gives a candidate diameter passing through that node. The maximum of these candidate values across all nodes yields the actual diameter of the graph.

How to compute diameter from each meeting point?

  • The diameter is found by recursively computing the height of each node based on its children.
  • For every node, its height is determined as 1 + the maximum height among its child nodes.
  • If the node is a leaf, its height is 0.
  • While computing heights, we track the longest path passing through each node.
  • This path is calculated by summing the two largest child heights and adding two edges that connect them through the current node.
  • The maximum such path length across all nodes gives the overall diameter of the tree.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//Driver Code Ends

void dfsPrune(int curr, vector<vector<int>>& adj, vector<bool>& visited) {
    if (visited[curr]) return;
    visited[curr] = true;
    for (int next : adj[curr]) {
        // remove back edge to make it a rooted tree
        auto it = find(adj[next].begin(), adj[next].end(), curr);
        if (it != adj[next].end())
            adj[next].erase(it);

        dfsPrune(next, adj, visited);
    }
}

int findHeight(int curr, vector<vector<int>>& adj, vector<int>& height) {
    if (height[curr] != -1) return height[curr];
    
    // leaf node has height = 0
    int temp = 0;
    for (int next : adj[curr]) {
        temp = max(temp, 1 + findHeight(next, adj, height));
    }
    return height[curr] = temp;
}

int diameter(vector<vector<int>>& adj) {
    int n = adj.size();
    vector<bool> visited(n, false);
    vector<int> height(n, -1);

    // root the tree at 0
    dfsPrune(0, adj, visited);

    fill(visited.begin(), visited.end(), false);
    findHeight(0, adj, height);

    int res = 0;
    for (int i = 0; i < n; i++) {
        int firstMax = -1, secondMax = -1;
    
        for (int next : adj[i]) {
            int hVal = height[next];
            if (hVal > firstMax) {
                secondMax = firstMax;
                firstMax = hVal;
            } else if (hVal > secondMax) {
                secondMax = hVal;
            }
        }
    
        // take 2 children with max distance from root = i
        if (firstMax != -1 && secondMax != -1)
            res = max(res, 2 + firstMax + secondMax);
        else if (firstMax != -1)
            res = max(res, 1 + firstMax);
    }

    return res;
}

//Driver Code Starts

void addEdge(vector<vector<int>>& adj, int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}

int main() {
    int V = 5;
    vector<vector<int>> adj(V);
    
    // creating adjacency list
    for (int i = 0; i < V; i++)
        adj[i] = vector<int>();

    addEdge(adj, 0, 1);
    addEdge(adj, 1, 2);
    addEdge(adj, 2, 3);
    addEdge(adj, 3, 4);
    
    int res = diameter(adj);
    cout << res << endl;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;
import java.util.ArrayList;

class GFG {
//Driver Code Ends

    static void dfsPrune(int curr, ArrayList<ArrayList<Integer>> adj, boolean[] visited) {
        if (visited[curr]) return;
        visited[curr] = true;
        for (int next : adj.get(curr)) {
            // remove back edge to make it a rooted tree
            adj.get(next).remove(Integer.valueOf(curr));
            dfsPrune(next, adj, visited);
        }
    }

    static int findHeight(int curr, ArrayList<ArrayList<Integer>> adj, int[] height) {
        if (height[curr] != -1) return height[curr];
        
        // leaf node has height = 0
        int temp = 0;
        for (int next : adj.get(curr)) {
            temp = Math.max(temp, 1 + findHeight(next, adj, height));
        }
        return height[curr] = temp;
    }

    static int diameter(ArrayList<ArrayList<Integer>> adj) {
        int n = adj.size();
        boolean[] visited = new boolean[n];
        int[] height = new int[n];
        Arrays.fill(height, -1);

        // root the tree at 0
        dfsPrune(0, adj, visited);

        Arrays.fill(visited, false);
        findHeight(0, adj, height);

        int res = 0;
        for (int i = 0; i < n; i++) {
            int firstMax = -1, secondMax = -1;
        
            for (int next : adj.get(i)) {
                int hVal = height[next];
                if (hVal > firstMax) {
                    secondMax = firstMax;
                    firstMax = hVal;
                } else if (hVal > secondMax) {
                    secondMax = hVal;
                }
            }
        
            // take 2 children with max distance from root = i
            if (firstMax != -1 && secondMax != -1)
                res = Math.max(res, 2 + firstMax + secondMax);
            else if (firstMax != -1)
                res = Math.max(res, 1 + firstMax);
        }


        return res;
    }

//Driver Code Starts

    static void addEdge(ArrayList<ArrayList<Integer>> adj, int u, int v) {
        adj.get(u).add(v);
        adj.get(v).add(u);
    }

    public static void main(String[] args) {
        int V = 5;
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.add(new ArrayList<>());

        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);
        
        int res = diameter(adj);
        System.out.println(res);
    }
}
//Driver Code Ends
Python
def dfsPrune(curr, adj, visited):
    if visited[curr]:
        return
    visited[curr] = True
    for next in adj[curr]:
        # remove back edge to make it a rooted tree
        adj[next].remove(curr)
        dfsPrune(next, adj, visited)

def findHeight(curr, adj, height):
    if height[curr] != -1:
        return height[curr]
    
    # leaf node has height = 0
    temp = 0
    for next_node in adj[curr]:
        temp = max(temp, 1 + findHeight(next_node, adj, height))
        
    height[curr] = temp
    return height[curr]

def diameter(adj):
    n = len(adj)
    visited = [False] * n
    height = [-1] * n

    # root the tree at 0
    dfsPrune(0, adj, visited)

    visited = [False] * n
    findHeight(0, adj, height)

    res = 0
    for i in range(n):
        firstMax = -1
        secondMax = -1
    
        for next in adj[i]:
            hVal = height[next]
            if hVal > firstMax:
                secondMax = firstMax
                firstMax = hVal
            elif hVal > secondMax:
                secondMax = hVal
    
        # take 2 children with max distance from root = i
        if firstMax != -1 and secondMax != -1:
            res = max(res, 2 + firstMax + secondMax)
        elif firstMax != -1:
            res = max(res, 1 + firstMax)
            

    return res
#Driver Code Starts

def addEdge(adj, u, v):
    adj[u].append(v)
    adj[v].append(u)
    
    
if __name__ == "__main__":
    V = 5
    adj = []
    
    # creating adjacency list
    for i in range(V):
        adj.append([])
        
    addEdge(adj, 0, 1)
    addEdge(adj, 1, 2)
    addEdge(adj, 2, 3)
    addEdge(adj, 3, 4)

    res = diameter(adj)
    print(res)
#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {
//Driver Code Ends

    static void dfsPrune(int curr, List<List<int>> adj, bool[] visited) {
        if (visited[curr]) return;
        visited[curr] = true;
        foreach (int next in adj[curr]) {
            // remove back edge to make it a rooted tree
            adj[next].Remove(curr);
            dfsPrune(next, adj, visited);
        }
    }

    static int findHeight(int curr, List<List<int>> adj, int[] height) {
        if (height[curr] != -1) return height[curr];
        
        // leaf node has height = 0
        int temp = 0;
        foreach (int next in adj[curr]) {
            temp = Math.Max(temp, 1 + findHeight(next, adj, height));
        }
        return height[curr] = temp;
    }

    static int diameter(List<List<int>> adj) {
        int n = adj.Count;
        bool[] visited = new bool[n];
        int[] height = Enumerable.Repeat(-1, n).ToArray();

        // root the tree at 0
        dfsPrune(0, adj, visited);

        Array.Fill(visited, false);
        findHeight(0, adj, height);

        int res = 0;
        for (int i = 0; i < n; i++) {
            int firstMax = -1, secondMax = -1;
        
            foreach (int next in adj[i]) {
                int hVal = height[next];
                if (hVal > firstMax) {
                    secondMax = firstMax;
                    firstMax = hVal;
                } else if (hVal > secondMax) {
                    secondMax = hVal;
                }
            }
        
            // take 2 children with max distance from root = i
            if (firstMax != -1 && secondMax != -1)
                res = Math.Max(res, 2 + firstMax + secondMax);
            else if (firstMax != -1)
                res = Math.Max(res, 1 + firstMax);
        }

        return res;
    }

//Driver Code Starts

    static void addEdge(List<List<int>> adj, int u, int v) {
        adj[u].Add(v);
        adj[v].Add(u);
    }

    static void Main() {
        int V = 5;
        List<List<int>> adj = new List<List<int>>();
        
        // creating adjacency list
        for (int i = 0; i < V; i++)
            adj.Add(new List<int>());
            
        addEdge(adj, 0, 1);
        addEdge(adj, 1, 2);
        addEdge(adj, 2, 3);
        addEdge(adj, 3, 4);

        int res = diameter(adj);
        Console.WriteLine(res);
    }
}
//Driver Code Ends
JavaScript
function dfsPrune(curr, adj, visited) {
    if (visited[curr]) return;
    visited[curr] = true;
    for (let next of adj[curr]) {
        // remove back edge to make it a rooted tree
        adj[next] = adj[next].filter(x => x !== curr);
        dfsPrune(next, adj, visited);
    }
}

function findHeight(curr, adj, height) {
    if (height[curr] !== -1) return height[curr];

    // leaf node has height = 0
    let temp = 0;
    for (let next of adj[curr]) {
        temp = Math.max(temp, 1 + findHeight(next, adj, height));
    }
    height[curr] = temp;
    return height[curr];
}

function diameter(adj) {
    const n = adj.length;
    let visited = Array(n).fill(false);
    let height = Array(n).fill(-1);

    // root the tree at 0
    dfsPrune(0, adj, visited);

    visited.fill(false);
    findHeight(0, adj, height);

    let res = 0;
    for (let i = 0; i < n; i++) {
        let firstMax = -1, secondMax = -1;
    
        for (let next of adj[i]) {
            let hVal = height[next];
            if (hVal > firstMax) {
                secondMax = firstMax;
                firstMax = hVal;
            } else if (hVal > secondMax) {
                secondMax = hVal;
            }
        }
    
        // take 2 children with max distance from root = i
        if (firstMax !== -1 && secondMax !== -1)
            res = Math.max(res, 2 + firstMax + secondMax);
        else if (firstMax !== -1)
            res = Math.max(res, 1 + firstMax);
    }

    return res;
}


//Driver Code Starts
function addEdge(adj, u, v) {
    adj[u].push(v);
    adj[v].push(u);
}

// Driver code

let V = 5;
let adj = [];

// creating adjacency list
for (let i = 0; i < V; i++)
    adj.push([]);

addEdge(adj, 0, 1);
addEdge(adj, 1, 2);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);

const res = diameter(adj);
console.log(res);
//Driver Code Ends

Output
4
Comment