Consider lines passing between nodes (in the following diagram). The diagonal sum in a binary tree is the sum of all node data lying between these lines. Given a Binary Tree of size n, print all diagonal sums.
For the following input tree, the output should be 9, 19, 42. 9 is the sum of 1, 3, and 5. 19 is the sum of 2, 6, 4, and 7. 42 is the sum of 9, 10, 11, and 12.
Examples:
Input:
Output: 7 4Â Explanation: Node 4 and its right child 3 lie on diagonal 0 giving sum 7, and node 1 with its right child 3 lie on diagonal 1 giving sum 4.
Using Level â Index to Group Diagonals - O(n log n) Time O(n) Space
The idea is to group nodes based on (level - index), as nodes on the same diagonal have the same value. Start from the root with (0, 0), add each nodeâs value to grid [level - index], move left to the next diagonal, and right to the same diagonal. This groups and sums nodes diagonal-wise efficiently.
Let us understand with an example: Start: grid = {} Step-by-step traversal:
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};voiddfs(Node*root,intlevel,intindex,map<int,int>&mp){if(!root)return;// correct diagonal key = level - indexmp[level-index]+=root->data;// left â next diagonaldfs(root->left,level+1,index-1,mp);// right â same diagonal directiondfs(root->right,level+1,index+1,mp);}vector<int>diagonalSum(Node*root){map<int,int>mp;dfs(root,0,0,mp);vector<int>ans;for(auto&it:mp){ans.push_back(it.second);}returnans;}// Driver codeintmain(){Node*root=newNode(10);root->left=newNode(8);root->right=newNode(2);root->left->left=newNode(3);root->left->right=newNode(5);root->right->left=newNode(2);vector<int>ans=diagonalSum(root);cout<<"Diagonal sum in a binary tree is: ";for(inti=0;i<ans.size();i++){cout<<ans[i]<<" ";}return0;}
Java
importjava.util.HashMap;importjava.util.ArrayList;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}publicclassGfG{staticvoiddfs(Noderoot,intlevel,intindex,HashMap<Integer,Integer>mp){if(root==null)return;// correct diagonal key = level - indexmp.put(level-index,mp.getOrDefault(level-index,0)+root.data);// left â next diagonaldfs(root.left,level+1,index-1,mp);// right â same diagonal directiondfs(root.right,level+1,index+1,mp);}staticArrayList<Integer>diagonalSum(Noderoot){HashMap<Integer,Integer>mp=newHashMap<>();dfs(root,0,0,mp);ArrayList<Integer>ans=newArrayList<>();for(intvalue:mp.values()){ans.add(value);}returnans;}publicstaticvoidmain(String[]args){Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);ArrayList<Integer>ans=diagonalSum(root);System.out.print("Diagonal sum in a binary tree is: ");for(inti=0;i<ans.size();i++){System.out.print(ans.get(i)+" ");}}}
Python
fromcollectionsimportdefaultdictclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=Nonedefdfs(root,level,index,mp):ifnotroot:return# correct diagonal key = level - indexmp[level-index]+=root.data# left â next diagonaldfs(root.left,level+1,index-1,mp)# right â same diagonal directiondfs(root.right,level+1,index+1,mp)defdiagonalSum(root):mp=defaultdict(int)dfs(root,0,0,mp)ans=[]forkeyinsorted(mp):ans.append(mp[key])returnans# Driver codeif__name__=='__main__':root=Node(10)root.left=Node(8)root.right=Node(2)root.left.left=Node(3)root.left.right=Node(5)root.right.left=Node(2)ans=diagonalSum(root)print('Diagonal sum in a binary tree is:',end=' ')foriinans:print(i,end=' ')
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}publicclassGfG{publicstaticvoiddfs(Noderoot,intlevel,intindex,Dictionary<int,int>mp){if(root==null)return;// correct diagonal key = level - indexif(mp.ContainsKey(level-index))mp[level-index]+=root.data;elsemp[level-index]=root.data;// left â next diagonaldfs(root.left,level+1,index-1,mp);// right â same diagonal directiondfs(root.right,level+1,index+1,mp);}publicstaticList<int>diagonalSum(Noderoot){Dictionary<int,int>mp=newDictionary<int,int>();dfs(root,0,0,mp);List<int>ans=newList<int>();foreach(varitinmp){ans.Add(it.Value);}returnans;}publicstaticvoidMain(){Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);List<int>ans=diagonalSum(root);Console.Write("Diagonal sum in a binary tree is: ");for(inti=0;i<ans.Count;i++){Console.Write(ans[i]+" ");}}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functiondfs(root,level,index,mp){if(!root)return;// correct diagonal key = level - indexif(mp.has(level-index)){mp.set(level-index,mp.get(level-index)+root.data);}else{mp.set(level-index,root.data);}// left â next diagonaldfs(root.left,level+1,index-1,mp);// right â same diagonal directiondfs(root.right,level+1,index+1,mp);}functiondiagonalSum(root){letmp=newMap();dfs(root,0,0,mp);letans=[];for(let[key,value]ofmp){ans.push(value);}returnans;}// Driver codeletroot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);letans=diagonalSum(root);console.log('Diagonal sum in a binary tree is:');console.log(ans.join(' '));
Output
Diagonal sum in a binary tree is: 12 15 3
Time Complexity-Â O(n log n) Space Complexity: O(n)
Using Diagonal Traversal (Map Based) - O(n log n) Time O(n) Space
The idea is to group nodes on the same diagonal and compute their sum. Assign a diagonal level (vd) starting from root as 0. For each node, add its value to map[vd]. Moving to the left child increases the diagonal (vd + 1), while moving to the right child keeps it the same. A map is used to store sums in sorted order of diagonals.
Algorithm:
Initialize a map to store (diagonal -> sum)
Traverse the tree using recursion
Update sum for each diagonal
Extract values from map into result vector
C++
// C++ Program to find diagonal sum in a Binary Tree#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};voidsolve(Node*root,intvd,map<int,int>&mp){if(!root)return;mp[vd]+=root->data;// left child -> vd + 1solve(root->left,vd+1,mp);// right child -> same vdsolve(root->right,vd,mp);}vector<int>diagonalSum(Node*root){map<int,int>mp;solve(root,0,mp);vector<int>res;for(autoit:mp)res.push_back(it.second);returnres;}// Driver codeintmain(){Node*root=newNode(10);root->left=newNode(8);root->right=newNode(2);root->left->left=newNode(3);root->left->right=newNode(5);root->right->left=newNode(2);vector<int>ans=diagonalSum(root);cout<<"Diagonal sum in a binary tree is: ";for(inti=0;i<ans.size();i++){cout<<ans[i]<<" ";}return0;}
C
#include<stdio.h>#include<stdlib.h>structNode{intdata;structNode*left;structNode*right;};structNode*createNode(intval){structNode*newNode=(structNode*)malloc(sizeof(structNode));newNode->data=val;newNode->left=NULL;newNode->right=NULL;returnnewNode;}voidsolve(structNode*root,intvd,int**mp,int*mpSize){if(!root)return;(*mp)[vd]+=root->data;// left child -> vd + 1solve(root->left,vd+1,mp,mpSize);// right child -> same vdsolve(root->right,vd,mp,mpSize);}int*diagonalSum(structNode*root,int*returnSize){intmpSize=1000;// assuming max size for simplicityint*mp=(int*)calloc(mpSize,sizeof(int));solve(root,0,&mp,&mpSize);intresSize=0;for(inti=0;i<mpSize;i++){if(mp[i]!=0)resSize++;}int*res=(int*)malloc(resSize*sizeof(int));intindex=0;for(inti=0;i<mpSize;i++){if(mp[i]!=0)res[index++]=mp[i];}*returnSize=resSize;returnres;}intmain(){structNode*root=createNode(10);root->left=createNode(8);root->right=createNode(2);root->left->left=createNode(3);root->left->right=createNode(5);root->right->left=createNode(2);intreturnSize;int*ans=diagonalSum(root,&returnSize);printf("Diagonal sum in a binary tree is: ");for(inti=0;i<returnSize;i++){printf("%d ",ans[i]);}printf("\n");free(ans);return0;}
Java
importjava.util.HashMap;importjava.util.Map;importjava.util.ArrayList;classNode{intdata;Nodeleft,right;publicNode(intitem){data=item;left=right=null;}}publicclassGfG{voidsolve(Noderoot,intvd,Map<Integer,Integer>mp){if(root==null)return;mp.put(vd,mp.getOrDefault(vd,0)+root.data);// left child -> vd + 1solve(root.left,vd+1,mp);// right child -> same vdsolve(root.right,vd,mp);}ArrayList<Integer>diagonalSum(Noderoot){Map<Integer,Integer>mp=newHashMap<>();solve(root,0,mp);ArrayList<Integer>res=newArrayList<>();for(Map.Entry<Integer,Integer>it:mp.entrySet())res.add(it.getValue());returnres;}// Driver codepublicstaticvoidmain(String[]args){GfGtree=newGfG();Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);ArrayList<Integer>ans=tree.diagonalSum(root);System.out.println("Diagonal sum in a binary tree is: ");for(inti=0;i<ans.size();i++){System.out.print(ans.get(i)+" ");}}}
Python
fromcollectionsimportdefaultdictclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=Nonedefsolve(root,vd,mp):ifnotroot:returnmp[vd]+=root.data# left child -> vd + 1solve(root.left,vd+1,mp)# right child -> same vdsolve(root.right,vd,mp)defdiagonalSum(root):mp=defaultdict(int)solve(root,0,mp)res=[]forkeyinmp:res.append(mp[key])returnres# Driver codeif__name__=='__main__':root=Node(10)root.left=Node(8)root.right=Node(2)root.left.left=Node(3)root.left.right=Node(5)root.right.left=Node(2)ans=diagonalSum(root)print('Diagonal sum in a binary tree is:',end=' ')foriinans:print(i,end=' ')
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}publicclassGfG{publicvoidSolve(Noderoot,intvd,Dictionary<int,int>mp){if(root==null)return;if(!mp.ContainsKey(vd))mp[vd]=0;mp[vd]+=root.data;// left child -> vd + 1Solve(root.left,vd+1,mp);// right child -> same vdSolve(root.right,vd,mp);}publicList<int>DiagonalSumMethod(Noderoot){Dictionary<int,int>mp=newDictionary<int,int>();Solve(root,0,mp);List<int>res=newList<int>();foreach(varitinmp)res.Add(it.Value);returnres;}publicstaticvoidMain(string[]args){GfGds=newGfG();Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);List<int>ans=ds.DiagonalSumMethod(root);Console.WriteLine("Diagonal sum in a binary tree is: ");foreach(intiinans)Console.Write(i+" ");}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}functionsolve(root,vd,mp){if(!root)return;if(!mp.has(vd))mp.set(vd,0);mp.set(vd,mp.get(vd)+root.data);// left child -> vd + 1solve(root.left,vd+1,mp);// right child -> same vdsolve(root.right,vd,mp);}functiondiagonalSum(root){letmp=newMap();solve(root,0,mp);letres=[];for(let[key,value]ofmp){res.push(value);}returnres;}// Driver codeletroot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);letans=diagonalSum(root);console.log('Diagonal sum in a binary tree is:');for(leti=0;i<ans.length;i++){console.log(ans[i]+' ');}
Output
Diagonal sum in a binary tree is: 12 15 3
Time Complexity: O(n log n) Space Complexity: O(n)
Iterative Level-Wise Diagonal Traversal Using a Queue - O(n) Time O(n) Space
The idea is to use a queue to store left children for future processing. The traversal always moves right first, accumulating the sum for the current diagonal. When the right chain ends, the next node is taken from the queue to begin a new diagonal, and this process continues until all nodes are covered.
Let us understand with an example:
Start: grid (list) = {} Step-by-step traversal:
Node 10 -> sum = 10 -> left (8 pushed), move right -> 2 -> grid = {0: 12}
Node 2 -> sum = 12 -> left (2 pushed), move right -> NULL
Move to next diagonal -> Node 8 -> grid = {0: 12, 2: 8}
Node 8 -> sum = 8 -> left (3 pushed), move right -> 5 -> grid = {0: 12, 2: 13}
Node 5 -> sum = 13 -> move right -> NULL
Move to next -> Node 2 -> grid = {0: 12, 2: 15}
Node 2 -> sum = 15 -> move right -> NULL
Move to next -> Node 3 -> grid = {0: 12, 2: 15, 4: 3}
// C++ program for the above approach#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intval){data=val;left=right=nullptr;}};// function for diagonal using queuevector<int>diagonalSum(Node*root){vector<int>ans;if(!root)returnans;queue<Node*>q;q.push(root);while(!q.empty()){intsize=q.size();intsum=0;// process current diagonalfor(inti=0;i<size;i++){Node*curr=q.front();q.pop();// traverse entire right chainwhile(curr){sum+=curr->data;if(curr->left)q.push(curr->left);curr=curr->right;}}ans.push_back(sum);}returnans;}// Driver codeintmain(){Node*root=newNode(10);root->left=newNode(8);root->right=newNode(2);root->left->left=newNode(3);root->left->right=newNode(5);root->right->left=newNode(2);vector<int>ans=diagonalSum(root);cout<<"Diagonal sum in a binary tree is: ";for(inti=0;i<ans.size();i++){cout<<ans[i]<<" ";}return0;}
Java
importjava.util.LinkedList;importjava.util.Queue;importjava.util.ArrayList;classNode{publicintdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}publicclassGfG{// function for diagonal using queuestaticArrayList<Integer>diagonalSum(Noderoot){ArrayList<Integer>ans=newArrayList<>();if(root==null)returnans;Queue<Node>q=newLinkedList<>();q.add(root);while(!q.isEmpty()){intsize=q.size();intsum=0;// process current diagonalfor(inti=0;i<size;i++){Nodecurr=q.poll();// traverse entire right chainwhile(curr!=null){sum+=curr.data;if(curr.left!=null)q.add(curr.left);curr=curr.right;}}ans.add(sum);}returnans;}publicstaticvoidmain(String[]args){Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);ArrayList<Integer>ans=diagonalSum(root);System.out.print("Diagonal sum in a binary tree is: ");for(inti=0;i<ans.size();i++){System.out.print(ans.get(i)+" ");}}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# function for diagonal using queuedefdiagonalSum(root):ans=[]ifnotroot:returnansq=deque([root])whileq:size=len(q)sum=0# process current diagonalforiinrange(size):curr=q.popleft()# traverse entire right chainwhilecurr:sum+=curr.dataifcurr.left:q.append(curr.left)curr=curr.rightans.append(sum)returnans# Driver codeif__name__=='__main__':root=Node(10)root.left=Node(8)root.right=Node(2)root.left.left=Node(3)root.left.right=Node(5)root.right.left=Node(2)ans=diagonalSum(root)print('Diagonal sum in a binary tree is:',end=' ')foriinans:print(i,end=' ')
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGfG{// function for diagonal using queuepublicList<int>diagonalSum(Noderoot){List<int>ans=newList<int>();if(root==null)returnans;Queue<Node>q=newQueue<Node>();q.Enqueue(root);while(q.Count>0){intsize=q.Count;intsum=0;// process current diagonalfor(inti=0;i<size;i++){Nodecurr=q.Dequeue();// traverse entire right chainwhile(curr!=null){sum+=curr.data;if(curr.left!=null)q.Enqueue(curr.left);curr=curr.right;}}ans.Add(sum);}returnans;}publicstaticvoidMain(string[]args){Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);GfGobj=newGfG();List<int>ans=obj.diagonalSum(root);Console.WriteLine("Diagonal sum in a binary tree is: ");for(inti=0;i<ans.Count;i++){Console.Write(ans[i]+" ");}}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// function for diagonal using queuefunctiondiagonalSum(root){letans=[];if(!root)returnans;letq=[];q.push(root);while(q.length>0){letsize=q.length;letsum=0;// process current diagonalfor(leti=0;i<size;i++){letcurr=q.shift();// traverse entire right chainwhile(curr){sum+=curr.data;if(curr.left)q.push(curr.left);curr=curr.right;}}ans.push(sum);}returnans;}// driver code(function(){letroot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);letans=diagonalSum(root);console.log("Diagonal sum in a binary tree is: ");for(leti=0;i<ans.length;i++){console.log(ans[i]+" ");}})();