Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximum sum of nodes in Binary tree such that no two are adjacent

  • Difficulty Level : Hard
  • Last Updated : 08 Dec, 2021

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 chosen 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:  

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.



In above binary tree chosen nodes are encircled 
and are not directly connected and their sum is
maximum possible.

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Method 1 
We can solve this problem by considering the fact that both node and its children can’t be in sum at the same time, so when we take a node into our sum we will call recursively for its grandchildren or if we don’t take this node then we will call for all its children nodes and finally we will choose maximum from both of the results. 
It can be seen easily that the above approach can lead to solving the same subproblem many times, for example in the above diagram node 1 calls node 4 and 5 when its value is chosen and node 3 also calls them when its value is not chosen so these nodes are processed more than once. We can stop solving these nodes more than once by memoizing the result at all nodes. 
In the below code, a map is used for memorizing the result which stores the result of the complete subtree rooted at a node in the map so that if it is called again, the value is not calculated again instead stored value from the map is returned directly. 

Please see the below code for a better understanding.

C++




// C++ program to find maximum sum from a subset of
// nodes of binary tree
#include <bits/stdc++.h>
using namespace std;
  
/* A binary tree node structure */
struct node
{
    int data;
    struct node *left, *right;
};
  
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
    struct node *temp = new struct node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
//  Declaration of methods
int sumOfGrandChildren(node* node);
int getMaxSum(node* node);
int getMaxSumUtil(node* node, map<struct node*, int>& mp);
  
// method returns maximum sum possible from subtrees rooted
// at grandChildrens of node 'node'
int sumOfGrandChildren(node* node, map<struct node*, int>& mp)
{
    int sum = 0;
  
    //  call for children of left child only if it is not NULL
    if (node->left)
        sum += getMaxSumUtil(node->left->left, mp) +
               getMaxSumUtil(node->left->right, mp);
  
    //  call for children of right child only if it is not NULL
    if (node->right)
        sum += getMaxSumUtil(node->right->left, mp) +
               getMaxSumUtil(node->right->right, mp);
  
    return sum;
}
  
//  Utility method to return maximum sum rooted at node 'node'
int getMaxSumUtil(node* node, map<struct node*, int>& mp)
{
    if (node == NULL)
        return 0;
  
    // If node is already processed then return calculated
    // value from map
    if (mp.find(node) != mp.end())
        return mp[node];
  
    //  take current node value and call for all grand children
    int incl = node->data + sumOfGrandChildren(node, mp);
  
    //  don't take current node value and call for all children
    int excl = getMaxSumUtil(node->left, mp) +
               getMaxSumUtil(node->right, mp);
  
    //  choose maximum from both above calls and store that in map
    mp[node] = max(incl, excl);
  
    return mp[node];
}
  
// Returns maximum sum from subset of nodes
// of binary tree under given constraints
int getMaxSum(node* node)
{
    if (node == NULL)
        return 0;
    map<struct node*, int> mp;
    return getMaxSumUtil(node, mp);
}
  
//  Driver code to test above methods
int main()
{
    node* 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;
    return 0;
}

Java




// Java program to find maximum sum from a subset of 
// nodes of binary tree 
import java.util.HashMap;
public class FindSumOfNotAdjacentNodes {
  
    // method returns maximum sum possible from subtrees rooted 
    // at grandChildrens of node 'node' 
    public static int sumOfGrandChildren(Node node, HashMap<Node,Integer> mp) 
    
        int sum = 0
        //  call for children of left child only if it is not NULL 
        if (node.left!=null
            sum += getMaxSumUtil(node.left.left, mp) + 
                   getMaxSumUtil(node.left.right, mp); 
    
        //  call for children of right child only if it is not NULL 
        if (node.right!=null
            sum += getMaxSumUtil(node.right.left, mp) + 
                   getMaxSumUtil(node.right.right, mp); 
        return sum; 
    }
  
    //  Utility method to return maximum sum rooted at node 'node' 
    public static int getMaxSumUtil(Node node, HashMap<Node,Integer> mp) 
    
        if (node == null
            return 0
    
        // If node is already processed then return calculated 
        // value from map 
        if(mp.containsKey(node))
            return mp.get(node);
    
        //  take current node value and call for all grand children 
        int incl = node.data + sumOfGrandChildren(node, mp); 
    
        //  don't take current node value and call for all children 
        int excl = getMaxSumUtil(node.left, mp) + 
                   getMaxSumUtil(node.right, mp); 
    
        //  choose maximum from both above calls and store that in map 
        mp.put(node,Math.max(incl, excl)); 
    
        return mp.get(node); 
    
  
    // Returns maximum sum from subset of nodes 
    // of binary tree under given constraints 
    public static int getMaxSum(Node node) 
    
        if (node == null
            return 0
        HashMap<Node,Integer> mp=new HashMap<>();
        return getMaxSumUtil(node, mp); 
    }
  
    public static void main(String args[]) 
    {
        Node root = new Node(1); 
        root.left = new Node(2); 
        root.right = new Node(3); 
        root.right.left = new Node(4); 
        root.right.right = new Node(5); 
        root.left.left = new Node(1);     
        System.out.print(getMaxSum(root));
    }
}
  
/* A binary tree node structure */
class Node 
    int data; 
    Node left, right; 
    Node(int data)
    {
        this.data=data;
        left=right=null;
    }
}; 
//This code is contributed by Gaurav Tiwari

Python3




# Python3 program to find 
# maximum sum from a subset 
# of nodes of binary tree
  
# A binary tree node structure 
class Node:
      
    def __init__(self, data):
      
        self.data = data
        self.left = None
        self.right = None
  
# Utility function to create 
# a new Binary Tree node 
def newNode(data):
  
    temp = Node(data)
    return temp;
  
# method returns maximum sum 
# possible from subtrees rooted
# at grandChildrens of node 'node'
def sumOfGrandChildren(node, mp):
  
    sum = 0;
  
    # call for children of left 
    # child only if it is not NULL
    if (node.left):
        sum += (getMaxSumUtil(node.left.left, mp) +
                getMaxSumUtil(node.left.right, mp));
  
    # call for children of right 
    # child only if it is not NULL
    if (node.right):
        sum += (getMaxSumUtil(node.right.left, mp) +
                getMaxSumUtil(node.right.right, mp));
  
    return sum;
  
# Utility method to return 
# maximum sum rooted at node 
# 'node'
def getMaxSumUtil(node, mp):
  
    if (node == None):
        return 0;
  
    # If node is already processed 
    # then return calculated
    # value from map
    if node in mp:
        return mp[node];
  
    # take current node value 
    # and call for all grand children
    incl = (node.data +
            sumOfGrandChildren(node, mp));
  
    # don't take current node 
    # value and call for all children
    excl = (getMaxSumUtil(node.left, mp) +
            getMaxSumUtil(node.right, mp));
  
    # choose maximum from both 
    # above calls and store that
    # in map
    mp[node] = max(incl, excl);
  
    return mp[node];
  
# Returns maximum sum from 
# subset of nodes of binary 
# tree under given constraints
def getMaxSum(node):
  
    if (node == None):
        return 0;
      
    mp = dict()
    return getMaxSumUtil(node, mp); 
  
# Driver code
if __name__=="__main__":
      
    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);
      
    print(getMaxSum(root))
      
# This code is contributed by Rutvik_56

C#




// C# program to find maximum sum from a subset of 
// nodes of binary tree
using System;
using System.Collections.Generic; 
  
public class FindSumOfNotAdjacentNodes
{
  
    // method returns maximum sum
    // possible from subtrees rooted 
    // at grandChildrens of node 'node' 
    public static int sumOfGrandChildren(Node node, 
                            Dictionary<Node,int> mp) 
    
        int sum = 0; 
          
        // call for children of left 
        // child only if it is not NULL 
        if (node.left != null
            sum += getMaxSumUtil(node.left.left, mp) + 
                getMaxSumUtil(node.left.right, mp); 
      
        // call for children of right 
        // child only if it is not NULL 
        if (node.right != null
            sum += getMaxSumUtil(node.right.left, mp) + 
                getMaxSumUtil(node.right.right, mp); 
        return sum; 
    }
  
    // Utility method to return maximum
    // sum rooted at node 'node' 
    public static int getMaxSumUtil(Node node,
                        Dictionary<Node,int> mp) 
    
        if (node == null
            return 0; 
      
        // If node is already processed then 
        // return calculated value from map 
        if(mp.ContainsKey(node))
            return mp[node];
      
        // take current node value and 
        // call for all grand children 
        int incl = node.data + sumOfGrandChildren(node, mp); 
      
        // don't take current node value and 
        // call for all children 
        int excl = getMaxSumUtil(node.left, mp) + 
                getMaxSumUtil(node.right, mp); 
      
        // choose maximum from both above 
        // calls and store that in map 
        mp.Add(node,Math.Max(incl, excl)); 
      
        return mp[node]; 
    
  
    // Returns maximum sum from subset of nodes 
    // of binary tree under given constraints 
    public static int getMaxSum(Node node) 
    
        if (node == null
            return 0; 
        Dictionary<Node,int> mp=new Dictionary<Node,int>();
        return getMaxSumUtil(node, mp); 
    }
  
    // Driver code
    public static void Main(String []args) 
    {
        Node root = new Node(1); 
        root.left = new Node(2); 
        root.right = new Node(3); 
        root.right.left = new Node(4); 
        root.right.right = new Node(5); 
        root.left.left = new Node(1);     
        Console.Write(getMaxSum(root));
    }
}
  
/* A binary tree node structure */
public class Node 
    public int data; 
    public Node left, right; 
    public Node(int data)
    {
        this.data=data;
        left=right=null;
    }
}; 
  
// This code has been contributed by 29AjayKumar

Javascript




<script>
  
// Javascript program to find maximum
// sum from a subset of nodes of binary tree
class Node
{
    constructor(data) 
    {
        this.left = null;
        this.right = null;
        this.data = data;
    }
}
  
// Method returns maximum sum possible 
// from subtrees rooted at grandChildrens
// of node 'node'
function sumOfGrandChildren(node, mp)
{
    let sum = 0;
      
    // Call for children of left child 
    // only if it is not NULL
    if (node.left!=null)
        sum += getMaxSumUtil(node.left.left, mp) +
               getMaxSumUtil(node.left.right, mp);
  
    // Call for children of right child
    // only if it is not NULL
    if (node.right!=null)
        sum += getMaxSumUtil(node.right.left, mp) +
               getMaxSumUtil(node.right.right, mp);
    return sum;
}
  
// Utility method to return maximum 
// sum rooted at node 'node'
function getMaxSumUtil(node, mp)
{
    if (node == null)
        return 0;
  
    // If node is already processed then return
    // calculated value from map
    if (mp.has(node))
        return mp.get(node);
  
    // Take current node value and call for
    // all grand children
    let incl = node.data + sumOfGrandChildren(node, mp);
  
    // Don't take current node value and call 
    // for all children
    let excl = getMaxSumUtil(node.left, mp) +
               getMaxSumUtil(node.right, mp);
  
    // Choose maximum from both above 
    // calls and store that in map
    mp.set(node,Math.max(incl, excl));
  
    return mp.get(node);
}
  
// Returns maximum sum from subset of nodes
// of binary tree under given constraints
function getMaxSum(node)
{
    if (node == null)
        return 0;
          
    let mp = new Map();
    return getMaxSumUtil(node, mp);
}
  
// Driver code
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.right.right = new Node(5);
root.left.left = new Node(1);    
  
document.write(getMaxSum(root));
  
// This code is contributed by divyeshrabadiya07
  
</script>
Output
11

This article is contributed by Utkarsh Trivedi.

 Method 2 (Using pair) 
Return a pair for each node in the binary tree such that the first of the pair indicates maximum sum when the data of a node is included and the second indicates 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<iostream>
using namespace std;
  
class Node
{
public:
    int data;
    Node* left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
  
pair<int, int> maxSumHelper(Node *root)
{
    if (root==NULL)
    {
        pair<int, int> sum(0, 0);
        return sum;
    }
    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);
  
    return sum;
}
  
int maxSum(Node *root)
{
    pair<int, int> res = maxSumHelper(root);
    return max(res.first, res.second);
}
  
// Driver code
int main()
{
    Node *root= new Node(10);
    root->left= new Node(1);
    root->left->left= new Node(2);
    root->left->left->left= new Node(1);
    root->left->right= new Node(3);
    root->left->right->left= new Node(4);
    root->left->right->right= new Node(5);
    cout << maxSum(root);
    return 0;
}

Java




// Java program to find maximum sum in Binary Tree 
// such that no two nodes are adjacent. 
public class FindSumOfNotAdjacentNodes {
  
    public static Pair maxSumHelper(Node root) 
    
        if (root==null
        
            Pair sum=new Pair(0, 0); 
            return sum; 
        
        Pair sum1 = maxSumHelper(root.left); 
        Pair sum2 = maxSumHelper(root.right); 
        Pair sum=new Pair(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); 
    
        return sum; 
    
  
    // Returns maximum sum from subset of nodes 
    // of binary tree under given constraints 
    public static int maxSum(Node root)
    {
        Pair res=maxSumHelper(root); 
        return Math.max(res.first, res.second);
    }
  
    public static void main(String args[]) {
        Node root= new Node(10); 
        root.left= new Node(1); 
        root.left.left= new Node(2); 
        root.left.left.left= new Node(1); 
        root.left.right= new Node(3); 
        root.left.right.left= new Node(4); 
        root.left.right.right= new Node(5); 
        System.out.print(maxSum(root)); 
    }
}
  
/* A binary tree node structure */
class Node 
    int data; 
    Node left, right; 
    Node(int data)
    {
        this.data=data;
        left=right=null;
    }
}; 
  
/* Pair class */
class Pair
{
    int first,second;
    Pair(int first,int second)
    {
        this.first=first;
        this.second=second;
    }
}
//This code is contributed by Gaurav Tiwari

Python3




# Python3 program to find maximum sum in Binary 
# Tree such that no two nodes are adjacent.
  
# Binary Tree Node 
  
""" utility that allocates a newNode 
with the given key """
class newNode: 
  
    # Construct to create a newNode 
    def __init__(self, key): 
        self.data = key
        self.left = None
        self.right = None
  
def maxSumHelper(root) :
  
    if (root == None): 
      
        sum = [0, 0
        return sum
      
    sum1 = maxSumHelper(root.left) 
    sum2 = maxSumHelper(root.right) 
    sum = [0, 0]
  
    # This node is included (Left and right 
    # children are not included) 
    sum[0] = sum1[1] + sum2[1] + root.data 
  
    # This node is excluded (Either left or 
    # right child is included) 
    sum[1] = (max(sum1[0], sum1[1]) + 
              max(sum2[0], sum2[1])) 
  
    return sum
  
def maxSum(root) :
  
    res = maxSumHelper(root) 
    return max(res[0], res[1]) 
  
# Driver Code 
if __name__ == '__main__':
    root = newNode(10
    root.left = newNode(1
    root.left.left = newNode(2
    root.left.left.left = newNode(1
    root.left.right = newNode(3
    root.left.right.left = newNode(4
    root.left.right.right = newNode(5)
    print(maxSum(root))
  
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

C#




// C# program to find maximum sum in Binary Tree 
// such that no two nodes are adjacent. 
using System;
  
public class FindSumOfNotAdjacentNodes 
  
    public static Pair maxSumHelper(Node root) 
    
        Pair sum;
        if (root == null
        
            sum=new Pair(0, 0); 
            return sum; 
        
        Pair sum1 = maxSumHelper(root.left); 
        Pair sum2 = maxSumHelper(root.right); 
        Pair sum3 = new Pair(0,0); 
      
        // This node is included (Left and 
        // right children are not included) 
        sum3.first = sum1.second + sum2.second + root.data; 
      
        // This node is excluded (Either left 
        // or right child is included) 
        sum3.second = Math.Max(sum1.first, sum1.second) + 
                    Math.Max(sum2.first, sum2.second); 
      
        return sum3; 
    
  
    // Returns maximum sum from subset of nodes 
    // of binary tree under given constraints 
    public static int maxSum(Node root) 
    
        Pair res=maxSumHelper(root); 
        return Math.Max(res.first, res.second); 
    
  
    // Driver code
    public static void Main() 
    
        Node root = new Node(10); 
        root.left = new Node(1); 
        root.left.left = new Node(2); 
        root.left.left.left = new Node(1); 
        root.left.right = new Node(3); 
        root.left.right.left = new Node(4); 
        root.left.right.right = new Node(5); 
        Console.Write(maxSum(root)); 
    
  
/* A binary tree node structure */
public class Node 
    public int data; 
    public Node left, right; 
    public Node(int data) 
    
        this.data = data; 
        left = right = null
    
}; 
  
/* Pair class */
public class Pair 
    public int first,second; 
    public Pair(int first,int second) 
    
        this.first = first; 
        this.second = second; 
    
  
/* This code is contributed PrinciRaj1992 */

Javascript




<script>
  
// JavaScript program to find maximum sum in Binary Tree 
// such that no two nodes are adjacent. 
  
/* A binary tree node structure */
class Node 
    constructor(data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}; 
  
/* Pair class */
class Pair 
    constructor(first, second)
    {
        this.first = first;
        this.second = second;
    }
  
function maxSumHelper(root) 
    var sum;
    if (root == null
    
        sum=new Pair(0, 0); 
        return sum; 
    
    var sum1 = maxSumHelper(root.left); 
    var sum2 = maxSumHelper(root.right); 
    var sum3 = new Pair(0,0); 
  
    // This node is included (Left and 
    // right children are not included) 
    sum3.first = sum1.second + sum2.second + root.data; 
  
    // This node is excluded (Either left 
    // or right child is included) 
    sum3.second = Math.max(sum1.first, sum1.second) + 
                Math.max(sum2.first, sum2.second); 
  
    return sum3; 
// Returns maximum sum from subset of nodes 
// of binary tree under given constraints 
function maxSum(root) 
    var res=maxSumHelper(root); 
    return Math.max(res.first, res.second); 
// Driver code
var root = new Node(10); 
root.left = new Node(1); 
root.left.left = new Node(2); 
root.left.left.left = new Node(1); 
root.left.right = new Node(3); 
root.left.right.left = new Node(4); 
root.left.right.right = new Node(5); 
document.write(maxSum(root)); 
  
  
</script>
Output
21

Time complexity: O(n)
Thanks to Surbhi Rastogi for suggesting this method.



Method 3(Using dynamic programming)

Store the maximum sum by including a node or excluding the node in a dp array or unordered map. Recursively calls for grandchildren of nodes if the node is included or calls for neighbours if the node is excluded.

C++




// C++ program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
  
class Node
{
public:
    int data;
    Node* left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
//declare map /dp array as global 
unordered_map<Node *, int> umap;
int maxSum(Node * root)
{
    //base case
    if(!root)return 0; 
      
    //if the max sum from the  node is already in map,return the value
    if(umap[root])return umap[root];
      
    //if the current node(root) is included in result
    //then find maximum sum
    int inc    =root->data;
      
    //if left of node exsists, addd their grandchildren
    if(root->left)
    {
        inc+=maxSum(root->left->left) + maxSum(root->left->right);
    }
    //if right of node exsist,add their grandchildren
    if(root->right)
    {
        inc+=maxSum(root->right->left)+maxSum(root->right->right);
    }
      
    //if the current node(root) is excluded, find the maximum sum
    int ex=maxSum(root->left)+maxSum(root->right);
      
    //store the maximum of including & excluding the node in map
    umap[root]=max(inc,ex);
      
}
  
// Driver code
int main()
{
    Node *root= new Node(10);
    root->left= new Node(1);
    root->left->left= new Node(2);
    root->left->left->left= new Node(1);
    root->left->right= new Node(3);
    root->left->right->left= new Node(4);
    root->left->right->right= new Node(5);
    cout << maxSum(root);
    return 0;
}
Output
21

Time complexity:O(n)
Auxiliary Space:O(n)

This article is contributed by Harsh.<https://auth.geeksforgeeks.org/user/harshchandekar10/profile>

  

 If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Method 4 (Simple tree traversal)

For every node, we find the following:

  1. Maximum sum of non-adjacent nodes including the node.
  2. Maximum sum of non-adjacent nodes excluding the node.

Now, we return both the values in the recursive call. The parent node of the previously calculated node gets the maximum sum (including & excluding) the child node. Accordingly, the parent now calculates the maximum sum(including & excluding) and returns. This process continues till root node. Finally, we return the max(sum including root, sum excluding root).

Time Complexity: O(n)

Space Complexity: O(1)

Python3




class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
  
  
class Solution:
  
    def max_sum(self, root):
        if not root:
            return 0, 0
  
        no_root_l, root_l = self.max_sum(root.left)
        no_root_r, root_r = self.max_sum(root.right)
  
        root_sum_max = max(root.data, root.data+no_root_l,
                           root.data+no_root_r, root.data+no_root_r+no_root_l)
        no_root_sum_max = max(root_l, root_r, root_l + root_r, no_root_l+no_root_r, 
                              root_l + no_root_r, root_r + no_root_l)
  
        return no_root_sum_max, root_sum_max
  
    def getMaxSum(self, root):
        return max(self.max_sum(root))

This method is contributed by Thatikonda Aditya.




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!