Given the root of a binary tree, find its diameter. The diameter of a tree is defined as the number of edges in the longest path between any two nodes.
Examples:
Input: The binary tree for this example is shown in the image below.
Output: 2 Explanation: The longest path has 2 edges ( the path 2 -> 1 -> 3 ).
Input: The binary tree for this example is shown in the image below.
Output: 4 Explanation: The longest path has 4 edges ( the path 5 -> 3 -> 2 -> 4 -> 6 ).
[Naive Approach] Calculate Height of Each Node - O(n2) Time and O(h) Space
The core idea involves recursively traversing the tree.
At each node,
Find the heights of its left and right subtrees
Update the maximum diameter if the sum of these heights is more than current maximum.
C++
#include#includeusingnamespacestd;// Node StructureclassNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Function to compute the height of a tree.intheight(Node*root){if(root==nullptr)return0;// If tree is not empty then height = 1 + max of left height and right heightsreturn1+max(height(root->left),height(root->right));}// Function to get diameter of a binary treeintdiameter(Node*root){if(root==nullptr)return0;// Get the height of left and right sub-treesintlheight=height(root->left);intrheight=height(root->right);// Get the diameter of left and right sub-treesintldiameter=diameter(root->left);intrdiameter=diameter(root->right);returnmax({lheight+rheight,ldiameter,rdiameter});}intmain(){Node*root=newNode(1);root->right=newNode(2);root->right->left=newNode(3);root->right->right=newNode(4);root->right->left->left=newNode(5);root->right->right->right=newNode(6);cout<<diameter(root)<<endl;return0;}
C
#include#include// Node StructurestructNode{intdata;structNode*left;structNode*right;};// Function to compute the height of a tree.intheight(structNode*root){if(root==NULL)return0;// If tree is not empty then height = 1 + max of left height and right heightsintleftHeight=height(root->left);intrightHeight=height(root->right);return1+(leftHeight>rightHeight?leftHeight:rightHeight);}// Function to get diameter of a binary treeintdiameter(structNode*root){if(root==NULL)return0;// Get the height of left and right sub-treesintlheight=height(root->left);intrheight=height(root->right);// Get the diameter of left and right sub-treesintldiameter=diameter(root->left);intrdiameter=diameter(root->right);// Diameter of current subtree intcurr=lheight+rheight;if(ldiameter>rdiameter&&ldiameter>curr)returnldiameter;elseif(rdiameter>ldiameter&&rdiameter>curr)returnrdiameter;returncurr;}structNode*createNode(intx){structNode*newNode=(structNode*)malloc(sizeof(structNode));newNode->data=x;newNode->left=NULL;newNode->right=NULL;returnnewNode;}intmain(){structNode*root=createNode(1);root->right=createNode(2);root->right->left=createNode(3);root->right->right=createNode(4);root->right->left->left=createNode(5);root->right->right->right=createNode(6);printf("%d\n",diameter(root));return0;}
Java
importjava.util.ArrayList;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGFG{// Function to compute the height of a tree.staticintheight(Noderoot){if(root==null)return0;// If tree is not empty then height = 1 + max of left height and right heightsreturn1+Math.max(height(root.left),height(root.right));}// Function to get diameter of a binary treestaticintdiameter(Noderoot){if(root==null)return0;// Get the height of left and right sub-treesintlheight=height(root.left);intrheight=height(root.right);// Get the diameter of left and right sub-treesintldiameter=diameter(root.left);intrdiameter=diameter(root.right);returnMath.max(lheight+rheight,Math.max(ldiameter,rdiameter));}publicstaticvoidmain(String[]args){Noderoot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);System.out.println(diameter(root));}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to compute the height of a treedefheight(root):ifrootisNone:return0# If tree is not empty then height = 1 + max of left height and right heightsreturn1+max(height(root.left),height(root.right))# Function to get diameter of a binary treedefdiameter(root):ifrootisNone:return0# Get the height of left and right sub-treeslheight=height(root.left)rheight=height(root.right)# Get the diameter of left and right sub-treesldiameter=diameter(root.left)rdiameter=diameter(root.right)returnmax(lheight+rheight,ldiameter,rdiameter)if__name__=="__main__":root=Node(1)root.right=Node(2)root.right.left=Node(3)root.right.right=Node(4)root.right.left.left=Node(5)root.right.right.right=Node(6)print(diameter(root))
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGFG{// Function to compute the height of a treestaticintheight(Noderoot){if(root==null)return0;// If tree is not empty then height = 1 + max of left height and right heightsreturn1+Math.Max(height(root.left),height(root.right));}// Function to get diameter of a binary treestaticintdiameter(Noderoot){if(root==null)return0;// Get the height of left and right sub-treesintlheight=height(root.left);intrheight=height(root.right);// Get the diameter of left and right sub-treesintldiameter=diameter(root.left);intrdiameter=diameter(root.right);returnMath.Max(lheight+rheight,Math.Max(ldiameter,rdiameter));}staticvoidMain(string[]args){Noderoot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);Console.WriteLine(diameter(root));}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to compute the height of a tree.functionheight(root){if(root===null)return0;// If tree is not empty then height = 1 + max of left height and right heightsreturn1+Math.max(height(root.left),height(root.right));}// Function to get diameter of a binary treefunctiondiameter(root){if(root===null)return0;// Get the height of left and right sub-treesconstlheight=height(root.left);constrheight=height(root.right);// Get the diameter of left and right sub-treesconstldiameter=diameter(root.left);constrdiameter=diameter(root.right);returnMath.max(lheight+rheight,ldiameter,rdiameter);}letroot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);console.log(diameter(root));
Output
4
[Expected Approach] Single Traversal - O(n) Time and O(h) Space
The core idea is to efficiently calculate the diameter, avoiding redundant height calculations.
For each node, we track two things simultaneously in recursion,
Height of current node (returned from recursion)
Maximum sum of left and right heights (or diameter). We track this using a shared variable among recursive calls.
We compare the maximum sum for current node with current maximum and update the result if needed.
Since both height and diameter are tracked in a single recursion, we get diameter using one traversal.
C++
#includeusingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Global variable to store the maximum diameterintmaxDiameter=0;intdiameterRecur(Node*root){if(!root)return0;// Find the height of left and right subtreeintlHeight=diameterRecur(root->left);intrHeight=diameterRecur(root->right);// Update the global max diameter if this node gives a longer pathif(lHeight+rHeight>maxDiameter)maxDiameter=lHeight+rHeight;// Return height of current subtreereturn1+max(lHeight,rHeight);}// Function to get diameter of a binary treeintdiameter(Node*root){maxDiameter=0;diameterRecur(root);returnmaxDiameter;}intmain(){Node*root=newNode(1);root->right=newNode(2);root->right->left=newNode(3);root->right->right=newNode(4);root->right->left->left=newNode(5);root->right->right->right=newNode(6);cout<<diameter(root)<<endl;return0;}
C
#include#include// Node StructurestructNode{intdata;structNode*left;structNode*right;};// Function to create a new NodestructNode*createNode(intx){structNode*node=(structNode*)malloc(sizeof(structNode));node->data=x;node->left=NULL;node->right=NULL;returnnode;}intmax(inta,intb){returna>b?a:b;}// Global variable to store the maximum diameterintmaxDiameter=0;intdiameterRecur(structNode*root){if(root==NULL)return0;// Find the height of left and right subtreeintlHeight=diameterRecur(root->left);intrHeight=diameterRecur(root->right);// Update the global max diameter if this node gives a longer pathif(lHeight+rHeight>maxDiameter)maxDiameter=lHeight+rHeight;// Return height of current subtreereturn1+max(lHeight,rHeight);}// Function to get diameter of a binary treeintdiameter(structNode*root){maxDiameter=0;diameterRecur(root);returnmaxDiameter;}intmain(){structNode*root=createNode(1);root->right=createNode(2);root->right->left=createNode(3);root->right->right=createNode(4);root->right->left->left=createNode(5);root->right->right->right=createNode(6);printf("%d\n",diameter(root));return0;}
Java
// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGFG{// Static variable to store maximum diameterstaticintmaxDiameter=0;// Recursive function to calculate height and update diameterstaticintdiameterRecur(Noderoot){if(root==null)return0;// Find the height of left and right subtreeintlHeight=diameterRecur(root.left);intrHeight=diameterRecur(root.right);// Update the global max diameter if this node gives a longer pathif(lHeight+rHeight>maxDiameter)maxDiameter=lHeight+rHeight;// Return height of current subtreereturn1+Math.max(lHeight,rHeight);}// Function to get diameter of a binary treestaticintdiameter(Noderoot){maxDiameter=0;diameterRecur(root);returnmaxDiameter;}publicstaticvoidmain(String[]args){Noderoot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);System.out.println(diameter(root));}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Global variable to store the maximum diametermaxDiameter=0# Recursive function to calculate height and update diameterdefdiameterRecur(root):globalmaxDiameterifrootisNone:return0# Find the height of left and right subtreelHeight=diameterRecur(root.left)rHeight=diameterRecur(root.right)# Update the global max diameter if this node gives a longer pathmaxDiameter=max(maxDiameter,lHeight+rHeight)# Return height of current subtreereturn1+max(lHeight,rHeight)# Function to get diameter of a binary treedefdiameter(root):globalmaxDiametermaxDiameter=0diameterRecur(root)returnmaxDiameterif__name__=="__main__":root=Node(1)root.right=Node(2)root.right.left=Node(3)root.right.right=Node(4)root.right.left.left=Node(5)root.right.right.right=Node(6)print(diameter(root))
C#
usingSystem;// Node StructureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGFG{// global variable to store maximum diameterstaticintmaxDiameter=0;// Recursive function which finds the diameter of the tree.staticintdiameterRecur(Noderoot){if(root==null)return0;// find the height of left and right subtreeintlHeight=diameterRecur(root.left);intrHeight=diameterRecur(root.right);// Check if diameter of root is greater than maxDiameter.maxDiameter=Math.Max(maxDiameter,lHeight+rHeight);// return the height of current subtree.return1+Math.Max(lHeight,rHeight);}// Function to get diameter of a binary treestaticintdiameter(Noderoot){maxDiameter=0;diameterRecur(root);returnmaxDiameter;}staticvoidMain(string[]args){Noderoot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);Console.WriteLine(diameter(root));}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// global variable to store the maximum diameterletmaxDiameter=0;// Recursive function which finds the diameter of the tree.functiondiameterRecur(root){if(root===null)return0;// find the height of left and right subtreeletlHeight=diameterRecur(root.left);letrHeight=diameterRecur(root.right);// Check if diameter of root is greater than maxDiameter.maxDiameter=Math.max(maxDiameter,lHeight+rHeight);// return the height of current subtree.return1+Math.max(lHeight,rHeight);}// Function to get diameter of a binary treefunctiondiameter(root){maxDiameter=0;diameterRecur(root);returnmaxDiameter;}letroot=newNode(1);root.right=newNode(2);root.right.left=newNode(3);root.right.right=newNode(4);root.right.left.left=newNode(5);root.right.right.right=newNode(6);console.log(diameter(root));