Maximum sum of nodes in Binary tree such that no two are adjacent
Last Updated :
09 Mar, 2023
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:
Explanation: In the above binary tree, chosen nodes are encircled and are not directly connected, and their sum is the maximum possible
Recommended: Please solve it on “PRACTICE” first before moving on to the solution.
The maximum sum of nodes in a Binary tree such that no two are adjacent using Recursion:
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 memorizing the result at all nodes
Follow the below steps to solve the problem:
- Create a map to memorize the results
- Recur to solve the problem for the root node
- If the root is NULL return 0 (Base Case)
- If the answer to this subproblem is already stored in the map, then return it
- Now either include the current node and recur for its grandchildren
- or don’t take the current node and recur for its left and the right child
- Save the answer to this problem equal to the maximum of the above two cases
- Return the answer
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node *left, *right;
};
struct node* newNode( int data)
{
struct node* temp = new struct node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int sumOfGrandChildren(node* node,
map< struct node*, int >& mp);
int getMaxSum(node* node);
int getMaxSumUtil(node* node, map< struct node*, int >& mp);
int sumOfGrandChildren(node* node,
map< struct node*, int >& mp)
{
int sum = 0;
if (node->left)
sum += getMaxSumUtil(node->left->left, mp)
+ getMaxSumUtil(node->left->right, mp);
if (node->right)
sum += getMaxSumUtil(node->right->left, mp)
+ getMaxSumUtil(node->right->right, mp);
return sum;
}
int getMaxSumUtil(node* node, map< struct node*, int >& mp)
{
if (node == NULL)
return 0;
if (mp.find(node) != mp.end())
return mp[node];
int incl = node->data + sumOfGrandChildren(node, mp);
int excl = getMaxSumUtil(node->left, mp)
+ getMaxSumUtil(node->right, mp);
mp[node] = max(incl, excl);
return mp[node];
}
int getMaxSum(node* node)
{
if (node == NULL)
return 0;
map< struct node*, int > mp;
return getMaxSumUtil(node, mp);
}
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
import java.util.HashMap;
public class FindSumOfNotAdjacentNodes {
public static int
sumOfGrandChildren(Node node, HashMap<Node, Integer> mp)
{
int sum = 0 ;
if (node.left != null )
sum += getMaxSumUtil(node.left.left, mp)
+ getMaxSumUtil(node.left.right, mp);
if (node.right != null )
sum += getMaxSumUtil(node.right.left, mp)
+ getMaxSumUtil(node.right.right, mp);
return sum;
}
public static int
getMaxSumUtil(Node node, HashMap<Node, Integer> mp)
{
if (node == null )
return 0 ;
if (mp.containsKey(node))
return mp.get(node);
int incl = node.data + sumOfGrandChildren(node, mp);
int excl = getMaxSumUtil(node.left, mp)
+ getMaxSumUtil(node.right, mp);
mp.put(node, Math.max(incl, excl));
return mp.get(node);
}
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));
}
}
class Node {
int data;
Node left, right;
Node( int data)
{
this .data = data;
left = right = null ;
}
};
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def newNode(data):
temp = Node(data)
return temp
def sumOfGrandChildren(node, mp):
sum = 0
if (node.left):
sum + = (getMaxSumUtil(node.left.left, mp) +
getMaxSumUtil(node.left.right, mp))
if (node.right):
sum + = (getMaxSumUtil(node.right.left, mp) +
getMaxSumUtil(node.right.right, mp))
return sum
def getMaxSumUtil(node, mp):
if (node = = None ):
return 0
if node in mp:
return mp[node]
incl = (node.data +
sumOfGrandChildren(node, mp))
excl = (getMaxSumUtil(node.left, mp) +
getMaxSumUtil(node.right, mp))
mp[node] = max (incl, excl)
return mp[node]
def getMaxSum(node):
if (node = = None ):
return 0
mp = dict ()
return getMaxSumUtil(node, mp)
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))
|
C#
using System;
using System.Collections.Generic;
public class FindSumOfNotAdjacentNodes {
public static int
sumOfGrandChildren(Node node, Dictionary<Node, int > mp)
{
int sum = 0;
if (node.left != null )
sum += getMaxSumUtil(node.left.left, mp)
+ getMaxSumUtil(node.left.right, mp);
if (node.right != null )
sum += getMaxSumUtil(node.right.left, mp)
+ getMaxSumUtil(node.right.right, mp);
return sum;
}
public static int
getMaxSumUtil(Node node, Dictionary<Node, int > mp)
{
if (node == null )
return 0;
if (mp.ContainsKey(node))
return mp[node];
int incl = node.data + sumOfGrandChildren(node, mp);
int excl = getMaxSumUtil(node.left, mp)
+ getMaxSumUtil(node.right, mp);
mp.Add(node, Math.Max(incl, excl));
return mp[node];
}
public static int getMaxSum(Node node)
{
if (node == null )
return 0;
Dictionary<Node, int > mp
= new Dictionary<Node, int >();
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);
Console.Write(getMaxSum(root));
}
}
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
};
|
Javascript
<script>
class Node
{
constructor(data)
{
this .left = null ;
this .right = null ;
this .data = data;
}
}
function sumOfGrandChildren(node, mp)
{
let sum = 0;
if (node.left!= null )
sum += getMaxSumUtil(node.left.left, mp) +
getMaxSumUtil(node.left.right, mp);
if (node.right!= null )
sum += getMaxSumUtil(node.right.left, mp) +
getMaxSumUtil(node.right.right, mp);
return sum;
}
function getMaxSumUtil(node, mp)
{
if (node == null )
return 0;
if (mp.has(node))
return mp.get(node);
let incl = node.data + sumOfGrandChildren(node, mp);
let excl = getMaxSumUtil(node.left, mp) +
getMaxSumUtil(node.right, mp);
mp.set(node,Math.max(incl, excl));
return mp.get(node);
}
function getMaxSum(node)
{
if (node == null )
return 0;
let mp = new Map();
return getMaxSumUtil(node, mp);
}
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));
</script>
|
Time complexity: O(N)
Auxiliary Space: O(N)
The maximum sum of nodes in a Binary tree such that no two are adjacent using pair:
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
Follow the below steps to solve the problem:
- Recur to solve the problem for the root node
- If the root is NULL return 0 (Base Case)
- Create a pair of <int, int> sum1 and set sum1 equal to the answer of root->left child
- Create a pair of <int, int> sum2 and set sum2 equal to the answer of root->right child
- Create a pair of <int, int> sum and set sum.first equal to sum1.second + sum2.second + root->data
- Set sum.second equal to the maximum of (sum1.first, sum1.second) + maximum of (sum2.first, sum2.second)
- Return sum
Below is the implementation of the above approach:
C++
#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;
}
};
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;
sum.first = sum1.second + sum2.second + root->data;
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);
}
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
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 );
sum.first = sum1.second + sum2.second + root.data;
sum.second = Math.max(sum1.first, sum1.second)
+ Math.max(sum2.first, sum2.second);
return sum;
}
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));
}
}
class Node {
int data;
Node left, right;
Node( int data)
{
this .data = data;
left = right = null ;
}
};
class Pair {
int first, second;
Pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
|
Python3
class 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 ]
sum [ 0 ] = sum1[ 1 ] + sum2[ 1 ] + root.data
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 ])
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))
|
C#
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);
sum3.first = sum1.second + sum2.second + root.data;
sum3.second = Math.Max(sum1.first, sum1.second)
+ Math.Max(sum2.first, sum2.second);
return sum3;
}
public static int maxSum(Node root)
{
Pair res = maxSumHelper(root);
return Math.Max(res.first, res.second);
}
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));
}
}
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
};
public class Pair {
public int first, second;
public Pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
|
Javascript
<script>
class Node
{
constructor(data)
{
this .data = data;
this .left = null ;
this .right = null ;
}
};
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);
sum3.first = sum1.second + sum2.second + root.data;
sum3.second = Math.max(sum1.first, sum1.second) +
Math.max(sum2.first, sum2.second);
return sum3;
}
function maxSum(root)
{
var res=maxSumHelper(root);
return Math.max(res.first, res.second);
}
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>
|
Time complexity: O(N)
Auxiliary Space: O(N)
Thanks to Surbhi Rastogi for suggesting this method.
The maximum sum of nodes in a Binary tree such that no two are adjacent using Dynamic programming:
Store the maximum sum by including a node or excluding the node in a dp array or unordered map. Recursively call for grandchildren of nodes if the node is included or calls for its neighbors if the node is excluded
Below is the implementation of the above approach:
C++
#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;
}
};
unordered_map<Node*, int > umap;
int maxSum(Node* root)
{
if (!root)
return 0;
if (umap[root])
return umap[root];
int inc = root->data;
if (root->left) {
inc += maxSum(root->left->left)
+ maxSum(root->left->right);
}
if (root->right) {
inc += maxSum(root->right->left)
+ maxSum(root->right->right);
}
int ex = maxSum(root->left) + maxSum(root->right);
umap[root] = max(inc, ex);
return max(inc, ex);
}
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
import java.io.*;
import java.util.*;
class GFG {
static HashMap<Node, Integer> umap = new HashMap<>();
static int maxSum(Node root)
{
if (root == null )
return 0 ;
if (umap.containsKey(root))
return umap.get(root);
int inc = root.data;
if (root.left != null ) {
inc += maxSum(root.left.left)
+ maxSum(root.left.right);
}
if (root.right != null ) {
inc += maxSum(root.right.left)
+ maxSum(root.right.right);
}
int ex = maxSum(root.left) + maxSum(root.right);
umap.put(root, Math.max(inc, ex));
return Math.max(inc, ex);
}
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.println(maxSum(root));
}
}
class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = null ;
right = null ;
}
};
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
umap = {}
def maxSum(root):
global umap
if (root = = None ):
return 0
if (root in umap):
return umap[root]
inc = root.data
if (root.left):
inc + = maxSum(root.left.left) + maxSum(root.left.right)
if (root.right):
inc + = maxSum(root.right.left) + maxSum(root.right.right)
ex = maxSum(root.left) + maxSum(root.right)
umap[root] = max (inc, ex)
return max (inc, ex)
if __name__ = = '__main__' :
root = Node( 10 )
root.left = Node( 1 )
root.left.left = Node( 2 )
root.left.left.left = Node( 1 )
root.left.right = Node( 3 )
root.left.right.left = Node( 4 )
root.left.right.right = Node( 5 )
print (maxSum(root))
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
};
class GFG {
static Dictionary<Node, int > umap
= new Dictionary<Node, int >();
static int maxSum(Node root)
{
if (root == null )
return 0;
if (umap.ContainsKey(root))
return umap[root];
int inc = root.data;
if (root.left != null ) {
inc += maxSum(root.left.left)
+ maxSum(root.left.right);
}
if (root.right != null ) {
inc += maxSum(root.right.left)
+ maxSum(root.right.right);
}
int ex = maxSum(root.left) + maxSum(root.right);
umap.Add(root, Math.Max(inc, ex));
return Math.Max(inc, ex);
}
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);
Console.Write(maxSum(root));
}
}
|
Javascript
<script>
class Node {
constructor(data)
{
this .data = data;
this .left = null ;
this .right = null ;
}
}
let umap = new Map();
function maxSum(root)
{
if (!root)
return 0;
if (umap.has(root))
return umap.get(root);
let inc = root.data;
if (root.left) {
inc += maxSum(root.left.left)
+ maxSum(root.left.right);
}
if (root.right) {
inc += maxSum(root.right.left)
+ maxSum(root.right.right);
}
let ex = maxSum(root.left) + maxSum(root.right);
umap.set(root,Math.max(inc, ex));
return Math.max(inc, ex);
}
let 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>
|
Time complexity: O(N)
Auxiliary Space: O(N)
<https://auth.geeksforgeeks.org/user/harshchandekar10/profile>
Approach: To solve the problem follow the below idea:
For every node, we find the following:
- The maximum sum of non-adjacent nodes including the node.
- The maximum sum of non-adjacent nodes excluding the node.
Now, we return both values in the recursive call. The parent node of the previously calculated node gets the maximum sum (including & excluding) of the child node. Accordingly, the parent now calculates the maximum sum(including & excluding) and returns. This process continues till the root node. Finally, we return the max(sum including root, sum excluding root)
Below is the implementation of the above approach:
C++
#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;
}
};
pair< int , int > max_sum(Node* root)
{
if (!root)
return { 0, 0 };
auto left = max_sum(root->left);
auto right = max_sum(root->right);
int no_root_l = left.first, root_l = left.second;
int no_root_r = right.first, root_r = right.second;
int root_sum_max
= max(max(root->data, root->data + no_root_l),
max(root->data + no_root_r,
root->data + no_root_r + no_root_l));
int no_root_sum_max = max(
max(root_l, root_r),
max(max(root_l + root_r, no_root_l + no_root_r),
max(root_l + no_root_r, root_r + no_root_l)));
return { no_root_sum_max, root_sum_max };
}
int getMaxSum(Node* root)
{
pair< int , int > ans = max_sum(root);
return max(ans.first, ans.second);
}
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<<getMaxSum(root)<<endl;
return 0;
}
|
Java
class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = null ;
right = null ;
}
};
class GFG {
public static List<Integer> max_sum(Node root)
{
if (root == null ) {
List<Integer> temp = new ArrayList<>();
temp.add( 0 );
temp.add( 0 );
return temp;
}
List<Integer> left = max_sum(root.left);
List<Integer> right = max_sum(root.right);
int no_root_l = left.get( 0 ), root_l = left.get( 1 );
int no_root_r = right.get( 0 ), root_r = right.get( 1 );
int root_sum_max = Math.max(
Math.max(root.data, root.data + no_root_l),
Math.max(root.data + no_root_r,
root.data + no_root_r + no_root_l));
int no_root_sum_max = Math.max(
Math.max(root_l, root_r),
Math.max(Math.max(root_l + root_r,
no_root_l + no_root_r),
Math.max(root_l + no_root_r,
root_r + no_root_l)));
List<Integer> ans = new ArrayList<>();
ans.add(no_root_sum_max);
ans.add(root_sum_max);
return ans;
}
public static int getMaxSum(Node root)
{
List<Integer> ans = max_sum(root);
return Math.max(ans.get( 0 ), ans.get( 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))
|
C#
class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = null ;
right = null ;
}
};
class GFG {
public static List< int > max_sum(Node root)
{
if (root == null ) {
List< int > temp = new List< int >();
temp.Add(0);
temp.Add(0);
return temp;
}
List< int > left = max_sum(root.left);
List< int > right = max_sum(root.right);
int no_root_l = left[0], root_l = left[1];
int no_root_r = right[0], root_r = right[1];
int root_sum_max = Math.Max(
Math.Max(root.data, root.data + no_root_l),
Math.Max(root.data + no_root_r,
root.data + no_root_r + no_root_l));
int no_root_sum_max = Math.Max(
Math.Max(root_l, root_r),
Math.Max(Math.Max(root_l + root_r,
no_root_l + no_root_r),
Math.Max(root_l + no_root_r,
root_r + no_root_l)));
List< int > ans = new List< int >();
ans.Add(no_root_sum_max);
ans.Add(root_sum_max);
return ans;
}
public static int getMaxSum(Node root)
{
List< int > ans = max_sum(root);
return Math.Max(ans[0], ans[1]);
}
}
|
Javascript
<script>
class Node{
constructor(val){
this .data = val
this .left = null
this .right = null
}
}
class Solution{
max_sum(root){
if (root == null )
return 0, 0
let no_root_l, root_l = this .max_sum(root.left)
let no_root_r, root_r = this .max_sum(root.right)
let root_sum_max = Math.max(root.data, root.data+no_root_l,
root.data+no_root_r, root.data+no_root_r+no_root_l)
let no_root_sum_max = Math.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
}
getMaxSum(root){
return Math.max( this .max_sum(root))
}
}
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
This method is contributed by Thatikonda Aditya.
The maximum sum of nodes in a Binary tree such that no two are adjacent using Memorization:
To solve the problem follow the below idea:
For every node, we can either choose it or leave it and pass on this information to children. Since we are passing on this information about the parent being selected or not, we don’t need to worry about the grandchildren of the node
So for every node, we do the following:
- If the parent is selected, we don’t select the current node and move on to the children.
- if the parent is not selected, we will either select or not select this node; in either case, we pass that info to the children
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *left, *right;
};
struct Node* newNode( int data)
{
struct Node* temp = new struct Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
vector<vector< int > > dp;
int cnt = 0;
Node* temp;
Node* giveIndex(Node* root)
{
if (root == NULL)
return NULL;
Node* newNode1 = newNode(cnt++);
newNode1->left = giveIndex(root->left);
newNode1->right = giveIndex(root->right);
return newNode1;
}
int solve(Node* root, int b, Node* temp)
{
if (root == NULL)
return 0;
if (dp[temp->data][b] != -1)
return dp[temp->data][b];
int res;
if (b == 0)
res = max(root->data
+ solve(root->right, 1, temp->right)
+ solve(root->left, 1, temp->left),
solve(root->right, 0, temp->right)
+ solve(root->left, 0, temp->left));
else
res = solve(root->right, 0, temp->right)
+ solve(root->left, 0, temp->left);
return dp[temp->data][b] = res;
}
int getMaxSum(Node* root)
{
dp = vector<vector< int > >(100, vector< int >(2, -1));
temp = giveIndex(root);
int res = solve(root, 0, temp);
return res;
}
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;
Node* root2 = newNode(10);
root2->left = newNode(1);
root2->left->left = newNode(2);
root2->left->left->left = newNode(1);
root2->left->right = newNode(3);
root2->left->right->left = newNode(4);
root2->left->right->right = newNode(5);
cout << getMaxSum(root2);
return 0;
}
|
Java
import java.util.HashMap;
class Node {
int data;
Node left, right;
Node( int data)
{
this .data = data;
left = right = null ;
}
};
class gfg {
static int [][] dp;
static int cnt = 0 ;
static Node temp;
static Node giveIndex(Node root)
{
if (root == null )
return null ;
Node newNode1 = new Node(cnt++);
newNode1.left = giveIndex(root.left);
newNode1.right = giveIndex(root.right);
return newNode1;
}
static int solve(Node root, int b, Node temp)
{
if (root == null )
return 0 ;
if (dp[temp.data][b] != - 1 )
return dp[temp.data][b];
int res;
if (b == 0 )
res = Math.max(
root.data + solve(root.right, 1 , temp.right)
+ solve(root.left, 1 , temp.left),
solve(root.right, 0 , temp.right)
+ solve(root.left, 0 , temp.left));
else
res = solve(root.right, 0 , temp.right)
+ solve(root.left, 0 , temp.left);
return dp[temp.data][b] = res;
}
static int getMaxSum(Node root)
{
dp = new int [ 100 ][ 2 ];
for ( int i = 0 ; i < 100 ; i++) {
dp[i][ 0 ] = - 1 ;
dp[i][ 1 ] = - 1 ;
}
temp = giveIndex(root);
int res = solve(root, 0 , temp);
return res;
}
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.println(getMaxSum(root));
Node root2 = new Node( 10 );
root2.left = new Node( 1 );
root2.left.left = new Node( 2 );
root2.left.left.left = new Node( 1 );
root2.left.right = new Node( 3 );
root2.left.right.left = new Node( 4 );
root2.left.right.right = new Node( 5 );
System.out.print(getMaxSum(root2));
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
dp = [[]]
cnt = 0
temp = newNode( 0 )
def giveIndex(root):
if (root = = None ):
return None
global cnt
cnt + = 1
newNode1 = newNode(cnt)
newNode1.left = giveIndex(root.left)
newNode1.right = giveIndex(root.right)
return newNode1
def solve(root, b, temp):
if (root = = None ):
return 0
if (dp[temp.data][b] ! = - 1 ):
return dp[temp.data][b]
res = 0
if (b = = 0 ):
res = max (root.data + solve(root.right, 1 , temp.right) + solve(root.left, 1 ,
temp.left), solve(root.right, 0 , temp.right) + solve(root.left, 0 , temp.left))
else :
res = solve(root.right, 0 , temp.right) + solve(root.left, 0 , temp.left)
dp[temp.data][b] = res
return res
def getMaxSum(root):
global dp
dp = [[ - 1 for x in range ( 2 )] for x in range ( 100 )]
temp = giveIndex(root)
res = solve(root, 0 , temp)
return res
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))
root2 = newNode( 10 )
root2.left = newNode( 1 )
root2.left.left = newNode( 2 )
root2.left.left.left = newNode( 1 )
root2.left.right = newNode( 3 )
root2.left.right.left = newNode( 4 )
root2.left.right.right = newNode( 5 )
print (getMaxSum(root2))
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
};
class gfg {
static int [, ] dp;
static int cnt = 0;
static Node temp;
static Node giveIndex(Node root)
{
if (root == null )
return null ;
Node newNode1 = new Node(cnt++);
newNode1.left = giveIndex(root.left);
newNode1.right = giveIndex(root.right);
return newNode1;
}
static int solve(Node root, int b, Node temp)
{
if (root == null )
return 0;
if (dp[temp.data, b] != -1)
return dp[temp.data, b];
int res;
if (b == 0)
res = Math.Max(
root.data + solve(root.right, 1, temp.right)
+ solve(root.left, 1, temp.left),
solve(root.right, 0, temp.right)
+ solve(root.left, 0, temp.left));
else
res = solve(root.right, 0, temp.right)
+ solve(root.left, 0, temp.left);
return dp[temp.data, b] = res;
}
static int getMaxSum(Node root)
{
dp = new int [100, 2];
for ( int i = 0; i < 100; i++) {
dp[i, 0] = -1;
dp[i, 1] = -1;
}
temp = giveIndex(root);
int res = solve(root, 0, temp);
return res;
}
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.WriteLine(getMaxSum(root));
Node root2 = new Node(10);
root2.left = new Node(1);
root2.left.left = new Node(2);
root2.left.left.left = new Node(1);
root2.left.right = new Node(3);
root2.left.right.left = new Node(4);
root2.left.right.right = new Node(5);
Console.Write(getMaxSum(root2));
}
}
|
Javascript
class Node{
constructor(val){
this .data = val
this .left = null
this .right = null
}
}
var temp;
var cnt = 0;
var dp = new Array(100);
for (let i=0;i<100;i++){
dp[i] = new Array(2);
}
function giveIndex(root){
if (root== null ){
return null ;
}
var newNode1 = new Node(cnt++);
newNode1.left = giveIndex(root.left);
newNode1.right = giveIndex(root.right);
return newNode1;
}
function solve(root, b, temp){
if (root== null ){
return null ;
}
if (dp[temp.data][b]!=-1){
return dp[temp.data][b];
}
var res;
if (b==0){
res = Math.max(root.data + solve(root.right, 1, temp.right)
+ solve(root.left, 1, temp.left),
solve(root.right, 0, temp.right)
+ solve(root.left, 0, temp.left));
}
else {
res = solve(root.right, 0, temp.right)
+ solve(root.left, 0, temp.left);
}
dp[temp.data][b] = res;
return dp[temp.data][b];
}
function getMaxSum(root){
for (let i=0;i<100;i++){
dp[i][0] = -1;
dp[i][1] = -1;
}
temp = giveIndex(root);
var res = solve(root, 0, temp);
return res;
}
var 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)+ "<br>" );
var root2 = new Node(10);
root2.left = new Node(1);
root2.left.left = new Node(2);
root2.left.left.left = new Node(1);
root2.left.right = new Node(3);
root2.left.right.left = new Node(4);
root2.left.right.right = new Node(5);
document.write(getMaxSum(root2));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
This method and implementation is contributed by Anirudh Singh.
Memorization
Please Login to comment...