Given a binary tree with a value associated with each node, we need to choose a subset of these nodes such that the sum of selected nodes is maximum under a constraint that no two chosen nodes in the subset should be directly connected, that is, if we have taken a node in our sum then we can’t take any of its children in consideration and vice versa.
Examples:
Input:
Output: 11 Explanation: The maximum sum is sum of node 11.
Input:
Output: 16 Explanation: The maximum sum is sum of nodes 1 4 5 6, i.e 16. These nodes are non adjacent.
[Naive Approach] Using Recursion - O(2^n) Time and O(n) Space
We can solve this problem by considering the fact that both node and its immediate children can’t be in sum at the same time.
Include the current node's value in the sum: In this case, we cannot include the values of its immediate children in the sum. Therefore, we recursively call the function on the grandchildren of the current node.
Exclude the current node's value in the sum: In this case, we are allowed to include the values of its immediate children in the sum. So, we recursively call the function on the immediate children of the current node.
Finally we will choose maximum from both of the results.
C++
// C++ program to find the maximum sum of // non-adjacent nodes in a binary tree.#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Utility method to return the maximum sum // rooted at the node 'curr'intgetMaxSumUtil(Node*node){if(node==nullptr){// If the node is null, the sum is 0return0;}// Calculate the maximum sum including the// current nodeintincl=node->data;// If the left child exists, include its contributionif(node->left){incl+=getMaxSumUtil(node->left->left)+getMaxSumUtil(node->left->right);}// If the right child exists, include its contributionif(node->right){incl+=getMaxSumUtil(node->right->left)+getMaxSumUtil(node->right->right);}// Calculate the maximum sum excluding // the current nodeintexcl=0;if(node->left){excl+=getMaxSumUtil(node->left);}if(node->right){excl+=getMaxSumUtil(node->right);}// The result for the current node is the// maximum of including or excluding itreturnmax(incl,excl);}intgetMaxSum(Node*root){// If the tree is empty, the maximum sum is 0if(root==nullptr){return0;}// Call the utility function to compute the// maximum sum for the entire treereturngetMaxSumUtil(root);}intmain(){// Creating a binary tree with the following structure:// 1// / \ // 2 3// / / \ // 1 4 5Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->right->left=newNode(4);root->right->right=newNode(5);root->left->left=newNode(1);cout<<getMaxSum(root)<<endl;return0;}
Java
// Java program to find the maximum sum // of non-adjacent nodes in a binary tree.importjava.util.*;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Utility method to return the maximum sum // rooted at the node 'node'staticintgetMaxSumUtil(Nodenode){if(node==null){// If the node is null, the sum is 0return0;}// Calculate the maximum sum including// the current nodeintincl=node.data;// If the left child exists, include its contributionif(node.left!=null){incl+=getMaxSumUtil(node.left.left)+getMaxSumUtil(node.left.right);}// If the right child exists, include// its contributionif(node.right!=null){incl+=getMaxSumUtil(node.right.left)+getMaxSumUtil(node.right.right);}// Calculate the maximum sum excluding// the current nodeintexcl=0;if(node.left!=null){excl+=getMaxSumUtil(node.left);}if(node.right!=null){excl+=getMaxSumUtil(node.right);}// The result for the current node is the// maximum of including or excluding itreturnMath.max(incl,excl);}staticintgetMaxSum(Noderoot){// If the tree is empty, the maximum sum is 0if(root==null){return0;}// Call the utility function to compute the // maximum sum for the entire treereturngetMaxSumUtil(root);}publicstaticvoidmain(String[]args){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);System.out.println(getMaxSum(root));}}
Python
# Python program to find the maximum sum # of non-adjacent nodes in a binary tree.classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Utility method to return the maximum # sum rooted at the node 'node'defgetMaxSumUtil(node):ifnodeisNone:# If the node is null, the sum is 0return0# Calculate the maximum sum including the current nodeincl=node.data# If the left child exists, include its contributionifnode.left:incl+=getMaxSumUtil(node.left.left)+getMaxSumUtil(node.left.right)# If the right child exists, include its contributionifnode.right:incl+=getMaxSumUtil(node.right.left)+getMaxSumUtil(node.right.right)# Calculate the maximum sum excluding the current nodeexcl=0ifnode.left:excl+=getMaxSumUtil(node.left)ifnode.right:excl+=getMaxSumUtil(node.right)# The result for the current node is the max of including or excluding itreturnmax(incl,excl)defgetMaxSum(root):# If the tree is empty, the maximum sum is 0ifrootisNone:return0returngetMaxSumUtil(root)if__name__=="__main__":# Creating a binary tree with the following structure:# 1# / \# 2 3# / / \# 1 4 5root=Node(1)root.left=Node(2)root.right=Node(3)root.right.left=Node(4)root.right.right=Node(5)root.left.left=Node(1)print(getMaxSum(root))
C#
// C# program to find the maximum sum // of non-adjacent nodes in a binary tree.usingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Utility method to return the maximum // sum rooted at the node 'node'staticintgetMaxSumUtil(Nodenode){if(node==null){// If the node is null, the sum is 0return0;}// Calculate the maximum sum including// the current nodeintincl=node.data;// If the left child exists, include its// contributionif(node.left!=null){incl+=getMaxSumUtil(node.left.left)+getMaxSumUtil(node.left.right);}// If the right child exists, include its contributionif(node.right!=null){incl+=getMaxSumUtil(node.right.left)+getMaxSumUtil(node.right.right);}// Calculate the maximum sum excluding // the current nodeintexcl=0;if(node.left!=null){excl+=getMaxSumUtil(node.left);}if(node.right!=null){excl+=getMaxSumUtil(node.right);}// The result for the current node is// the maximum of including or excluding itreturnMath.Max(incl,excl);}staticintgetMaxSum(Noderoot){// If the tree is empty, the maximum sum is 0if(root==null){return0;}// Call the utility function to compute // the maximum sum for the entire treereturngetMaxSumUtil(root);}staticvoidMain(string[]args){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);Console.WriteLine(getMaxSum(root));}}
JavaScript
// JavaScript program to find the maximum sum// of non-adjacent nodes in a binary tree.classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Utility method to return the maximum sum // rooted at the node 'node'functiongetMaxSumUtil(node){if(node===null){// If the node is null, the sum is 0return0;}// Calculate the maximum sum including the// current nodeletincl=node.data;// If the left child exists, include its contributionif(node.left){incl+=getMaxSumUtil(node.left.left)+getMaxSumUtil(node.left.right);}// If the right child exists, include its contributionif(node.right){incl+=getMaxSumUtil(node.right.left)+getMaxSumUtil(node.right.right);}// Calculate the maximum sum excluding // the current nodeletexcl=0;if(node.left){excl+=getMaxSumUtil(node.left);}if(node.right){excl+=getMaxSumUtil(node.right);}// The result for the current node is the // maximum of including or excluding itreturnMath.max(incl,excl);}functiongetMaxSum(root){// If the tree is empty, the maximum sum is 0if(root===null)return0;// Call the utility function to compute // the maximum sum for the entire treereturngetMaxSumUtil(root);}// Driver Code // Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);console.log(getMaxSum(root));
Output
11
[Expected Approach 1] Using Top-Down DP (Memoization) - O(n) Time and O(n) Space
The naive approach leads to recalculating results for the same nodes multiple times. For example, if we include the root node, we recursively compute the sum for its grandchildren (nodes 4 and 5). But if we exclude the root, we compute the sum for its children, and node 3 also computes the sum for its children (4 and 5 again).
When a node's value is needed again, we directly return it from the map instead of recalculating.
C++
// C++ program to find the maximum sum of // non-adjacent nodes in a binary tree using memoization.#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Utility method to return the maximum sum rooted// at the node 'node'intgetMaxSumUtil(Node*node,unordered_map<Node*,int>&memo){if(node==nullptr){// If the node is null, the sum is 0return0;}// If the result is already computed, return it from memoif(memo.find(node)!=memo.end()){returnmemo[node];}// Calculate the maximum sum including the current nodeintincl=node->data;// If the left child exists, include its grandchildrenif(node->left){incl+=getMaxSumUtil(node->left->left,memo)+getMaxSumUtil(node->left->right,memo);}// If the right child exists, include its grandchildrenif(node->right){incl+=getMaxSumUtil(node->right->left,memo)+getMaxSumUtil(node->right->right,memo);}// Calculate the maximum sum excluding the current nodeintexcl=getMaxSumUtil(node->left,memo)+getMaxSumUtil(node->right,memo);// Store the result in memo and return // the maximum of incl and exclmemo[node]=max(incl,excl);returnmemo[node];}// Function to compute the maximum// sum of non-adjacent nodesintgetMaxSum(Node*root){unordered_map<Node*,int>memo;returngetMaxSumUtil(root,memo);}intmain(){// Creating a binary tree with the following structure:// 1// / \ // 2 3// / / \ // 1 4 5Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->right->left=newNode(4);root->right->right=newNode(5);root->left->left=newNode(1);cout<<getMaxSum(root)<<endl;return0;}
Java
// Java program to find the maximum sum of // non-adjacent nodes in a binary tree using memoization.importjava.util.HashMap;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Utility method to return the maximum // sum rooted at the node 'node'staticintgetMaxSumUtil(Nodenode,HashMap<Node,Integer>memo){if(node==null){// If the node is null, the sum is 0return0;}// If the result is already computed, // return it from memoif(memo.containsKey(node)){returnmemo.get(node);}// Calculate the maximum sum including // the current nodeintincl=node.data;// If the left child exists, include its grandchildrenif(node.left!=null){incl+=getMaxSumUtil(node.left.left,memo)+getMaxSumUtil(node.left.right,memo);}// If the right child exists, include // its grandchildrenif(node.right!=null){incl+=getMaxSumUtil(node.right.left,memo)+getMaxSumUtil(node.right.right,memo);}// Calculate the maximum sum excluding the current nodeintexcl=getMaxSumUtil(node.left,memo)+getMaxSumUtil(node.right,memo);// Store the result in memo and return // the maximum of incl and exclmemo.put(node,Math.max(incl,excl));returnmemo.get(node);}// Function to compute the maximum sum of// non-adjacent nodesstaticintgetMaxSum(Noderoot){HashMap<Node,Integer>memo=newHashMap<>();returngetMaxSumUtil(root,memo);}publicstaticvoidmain(String[]args){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);System.out.println(getMaxSum(root));}}
Python
# Python program to find the maximum sum of # non-adjacent nodes in a binary tree using memoization.classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Utility method to return the maximum sum rooted # at the node 'node'defgetMaxSumUtil(node,memo):ifnodeisNone:# If the node is null, the sum is 0return0# If the result is already computed, return it from memoifnodeinmemo:returnmemo[node]# Calculate the maximum sum including the current nodeincl=node.data# If the left child exists, include its grandchildrenifnode.left:incl+=getMaxSumUtil(node.left.left,memo)+ \
getMaxSumUtil(node.left.right,memo)# If the right child exists, include its grandchildrenifnode.right:incl+=getMaxSumUtil(node.right.left,memo)+ \
getMaxSumUtil(node.right.right,memo)# Calculate the maximum sum excluding the current nodeexcl=getMaxSumUtil(node.left,memo)+ \
getMaxSumUtil(node.right,memo)# Store the result in memo and return memo[node]=max(incl,excl)returnmemo[node]# Function to compute the maximum sum of# non-adjacent nodesdefgetMaxSum(root):memo={}returngetMaxSumUtil(root,memo)if__name__=="__main__":# Creating a binary tree with the following structure:# 1# / \# 2 3# / / \# 1 4 5root=Node(1)root.left=Node(2)root.right=Node(3)root.right.left=Node(4)root.right.right=Node(5)root.left.left=Node(1)print(getMaxSum(root))
C#
// C# program to find the maximum sum of // non-adjacent nodes in a binary tree using memoization.usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Utility method to return the maximum // sum rooted at the node 'node'staticintgetMaxSumUtil(Nodenode,Dictionary<Node,int>memo){if(node==null){// If the node is null, the sum is 0return0;}// If the result is already computed,// return it from memoif(memo.ContainsKey(node)){returnmemo[node];}// Calculate the maximum sum including // the current nodeintincl=node.data;// If the left child exists, include its// grandchildrenif(node.left!=null){incl+=getMaxSumUtil(node.left.left,memo)+getMaxSumUtil(node.left.right,memo);}// If the right child exists, include // its grandchildrenif(node.right!=null){incl+=getMaxSumUtil(node.right.left,memo)+getMaxSumUtil(node.right.right,memo);}// Calculate the maximum sum excluding the // current nodeintexcl=getMaxSumUtil(node.left,memo)+getMaxSumUtil(node.right,memo);// Store the result in memo and return memo[node]=Math.Max(incl,excl);returnmemo[node];}staticintgetMaxSum(Noderoot){Dictionary<Node,int>memo=newDictionary<Node,int>();returngetMaxSumUtil(root,memo);}staticvoidMain(){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);Console.WriteLine(getMaxSum(root));}}
JavaScript
// JavaScript program to find the maximum sum of // non-adjacent nodes in a binary tree using memoization.classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Utility method to return the maximum sum// rooted at the node 'node'functiongetMaxSumUtil(node,memo){if(node===null){// If the node is null, the sum is 0return0;}// If the result is already computed, return it from memoif(memo.has(node)){returnmemo.get(node);}// Calculate the maximum sum including the current nodeletincl=node.data;// If the left child exists, include its grandchildrenif(node.left){incl+=getMaxSumUtil(node.left.left,memo)+getMaxSumUtil(node.left.right,memo);}// If the right child exists, include its grandchildrenif(node.right){incl+=getMaxSumUtil(node.right.left,memo)+getMaxSumUtil(node.right.right,memo);}// Calculate the maximum sum excluding the // current nodeletexcl=getMaxSumUtil(node.left,memo)+getMaxSumUtil(node.right,memo);// Store the result in memo and return memo.set(node,Math.max(incl,excl));returnmemo.get(node);}// Function to compute the maximum sum of// non-adjacent nodesfunctiongetMaxSum(root){letmemo=newMap();returngetMaxSumUtil(root,memo);}// Driver Code // Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5constroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);console.log(getMaxSum(root));
Output
11
[Expected Approach 2] Using Pairs - O(n) Time and O(h) Space
Return a pair for each node in the binary tree such that the first of the pair indicates the maximum sum when the data of a node is included and the second indicates the maximum sum when the data of a particular node is not included.
C++
// C++ program to find maximum sum in Binary Tree// such that no two nodes are adjacent.#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intd){data=d;left=nullptr;right=nullptr;}};pair<int,int>maxSumHelper(Node*root){if(root==nullptr){pair<int,int>sum(0,0);returnsum;}pair<int,int>sum1=maxSumHelper(root->left);pair<int,int>sum2=maxSumHelper(root->right);pair<int,int>sum;// This node is included (Left and right children// are not included)sum.first=sum1.second+sum2.second+root->data;// This node is excluded (Either left or right// child is included)sum.second=max(sum1.first,sum1.second)+max(sum2.first,sum2.second);returnsum;}// Returns maximum sum from subset of nodes// of binary tree under given constraintsintgetMaxSum(Node*root){pair<int,int>res=maxSumHelper(root);returnmax(res.first,res.second);}intmain(){// Creating a binary tree with the following structure:// 1// / \ // 2 3// / / \ // 1 4 5Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->right->left=newNode(4);root->right->right=newNode(5);root->left->left=newNode(1);cout<<getMaxSum(root);return0;}
Java
// Java program to find maximum sum in Binary Tree// such that no two nodes are adjacent.classNode{intdata;Nodeleft,right;Node(intdata){this.data=data;left=right=null;}};classPair{intfirst,second;Pair(intfirst,intsecond){this.first=first;this.second=second;}}classGfG{staticPairmaxSumHelper(Noderoot){if(root==null){Pairsum=newPair(0,0);returnsum;}Pairsum1=maxSumHelper(root.left);Pairsum2=maxSumHelper(root.right);Pairsum=newPair(0,0);// This node is included (Left and right children// are not included)sum.first=sum1.second+sum2.second+root.data;// This node is excluded (Either left or right// child is included)sum.second=Math.max(sum1.first,sum1.second)+Math.max(sum2.first,sum2.second);returnsum;}// Returns maximum sum from subset of nodes// of binary tree under given constraintsstaticintgetMaxSum(Noderoot){Pairres=maxSumHelper(root);returnMath.max(res.first,res.second);}publicstaticvoidmain(Stringargs[]){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);System.out.print(getMaxSum(root));}}
Python
# Python program to find the maximum sum in a Binary Tree# such that no two nodes are adjacent.classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Helper function to find the maximum sumdefmaxSumHelper(root):ifrootisNone:return(0,0)# Recursively get the maximum sum for left# and right subtreesleftSum=maxSumHelper(root.left)rightSum=maxSumHelper(root.right)# This node is included (children are not included)include=leftSum[1]+rightSum[1]+root.data# This node is excluded (children may be included)exclude=max(leftSum[0],leftSum[1])+ \
max(rightSum[0],rightSum[1])return(include,exclude)# Function to get the maximum sum with # the given constraintsdefgetMaxSum(root):result=maxSumHelper(root)returnmax(result[0],result[1])if__name__=="__main__":# Creating a binary tree with the following structure:# 1# / \# 2 3# / / \# 1 4 5root=Node(1)root.left=Node(2)root.right=Node(3)root.right.left=Node(4)root.right.right=Node(5)root.left.left=Node(1)print(getMaxSum(root))
C#
// C# program to find the maximum sum in a Binary Tree// such that no two nodes are adjacent.usingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;left=null;right=null;}}classGfG{// Helper function to find the maximum sumstatic(intinclude,intexclude)maxSumHelper(Noderoot){if(root==null)return(0,0);// Recursively get the maximum sum for left// and right subtreesvarleftSum=maxSumHelper(root.left);varrightSum=maxSumHelper(root.right);// This node is included (children are// not included)intinclude=leftSum.exclude+rightSum.exclude+root.data;// This node is excluded (children may be included)intexclude=Math.Max(leftSum.include,leftSum.exclude)+Math.Max(rightSum.include,rightSum.exclude);return(include,exclude);}// Function to get the maximum sum with the // given constraintsstaticintgetMaxSum(Noderoot){varresult=maxSumHelper(root);returnMath.Max(result.include,result.exclude);}staticvoidMain(){// Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);Console.WriteLine(getMaxSum(root));}}
JavaScript
// JavaScript program to find the maximum sum in a Binary Tree// such that no two nodes are adjacent.classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Helper function to find the maximum sumfunctionmaxSumHelper(root){if(root===null){return[0,0];}// Recursively get the maximum sum for left and right subtreesconstleftSum=maxSumHelper(root.left);constrightSum=maxSumHelper(root.right);// This node is included (children are not included)constinclude=leftSum[1]+rightSum[1]+root.data;// This node is excluded (children may be included)constexclude=Math.max(leftSum[0],leftSum[1])+Math.max(rightSum[0],rightSum[1]);return[include,exclude];}// Function to get the maximum sum with the given constraintsfunctiongetMaxSum(root){constresult=maxSumHelper(root);returnMath.max(result[0],result[1]);}// Driver Code // Creating a binary tree with the following structure:// 1// / \// 2 3// / / \// 1 4 5letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.right.left=newNode(4);root.right.right=newNode(5);root.left.left=newNode(1);console.log(getMaxSum(root));
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.