Diameter of a Graph Without Cycles (original) (raw)

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}.

Table of Content

[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 #include using namespace std;

//Driver Code Ends

int farthestNode(int curr, vector& visited, vector<vector>& 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>& 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>& adj, int u, int v) { adj[u].push_back(v); adj[v].push_back(u); }

int main() { int V = 5; vector<vector> 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> 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

`

[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 #include using namespace std;

//Driver Code Ends

void farthestNode(int curr, vector<vector>& adj, int currentDist, vector& dist, vector& 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>& adj) { int n = adj.size(); vector dist = {0, 0}; vector 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>& adj, int u, int v) { adj[u].push_back(v); adj[v].push_back(u); }

int main() { int V = 5; vector<vector> 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> 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

`

[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?

//Driver Code Starts #include #include #include using namespace std;

//Driver Code Ends

void dfsPrune(int curr, vector<vector>& adj, vector& 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>& adj, vector& 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>& adj) { int n = adj.size(); vector visited(n, false); vector 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>& adj, int u, int v) { adj[u].push_back(v); adj[v].push_back(u); }

int main() { int V = 5; vector<vector> 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

`