Maximum sub-tree sum in a Binary Tree such that the sub-tree is also a BST

Given a binary tree, the task is to print the maximum sum of nodes of a sub-tree which is also a Binary Search Tree.

Examples:

Input : 
       7
      /  \
     12    2
    /  \    \
   11  13    5
  /         / \
 2         1   38  

Output:44
BST rooted under node 5 has the maximum sum
       5
      / \
     1   38

Input:
      5
     /  \
    9    2
   /      \
  6        3
 / \
8   7   

Output: 8
Here each leaf node represents a binary search tree 
also a BST with sum 5 exists
     2
      \
       3
But the leaf node 8 has the maximum sum.

Approach: We traverse tree in bottom up manner. For every traversed node, we store the information of maximum and minimum of that subtree, a variable isBST to store if it is a BST, variable currmax to store the maximum sum of BST found till now, and a variable sum to store the sum of Left and Right subtree(which is also a BST) rooted under the current node.



Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Binary tree node
struct Node {
    struct Node* left;
    struct Node* right;
    int data;
  
    Node(int data)
    {
        this->data = data;
        this->left = NULL;
        this->right = NULL;
    }
};
  
// Information stored in every
// node during bottom up traversal
struct Info {
  
    // Max Value in the subtree
    int max;
  
    // Min value in the subtree
    int min;
  
    // If subtree is BST
    bool isBST;
  
    // Sum of the nodes of the sub-tree
    // rooted under the current node
    int sum;
  
    // Max sum of BST found till now
    int currmax;
};
  
// Returns information about subtree such as
// subtree with maximum sum which is also a BST
Info MaxSumBSTUtil(struct Node* root, int& maxsum)
{
    // Base case
    if (root == NULL)
        return { INT_MIN, INT_MAX, true, 0, 0 };
  
    // If current node is a leaf node then
    // return from the function and store
    // information about the leaf node
    if (root->left == NULL && root->right == NULL) {
        maxsum = max(maxsum, root->data);
        return { root->data, root->data, true, root->data, maxsum };
    }
  
    // Store information about the left subtree
    Info L = MaxSumBSTUtil(root->left, maxsum);
  
    // Store information about the right subtree
    Info R = MaxSumBSTUtil(root->right, maxsum);
  
    Info BST;
  
    // If the subtree rooted under the current node
    // is a BST
    if (L.isBST && R.isBST && L.max < root->data && R.min > root->data) {
  
        BST.max = max(root->data, max(L.max, R.max));
        BST.min = min(root->data, min(L.min, R.min));
  
        maxsum = max(maxsum, R.sum + root->data + L.sum);
        BST.sum = R.sum + root->data + L.sum;
  
        // Update the current maximum sum
        BST.currmax = maxsum;
  
        BST.isBST = true;
        return BST;
    }
  
    // If the whole tree is not a BST then
    // update the current maximum sum
    BST.isBST = false;
    BST.currmax = maxsum;
    BST.sum = R.sum + root->data + L.sum;
  
    return BST;
}
  
// Function to return the maximum
// sum subtree which is also a BST
int MaxSumBST(struct Node* root)
{
    int maxsum = INT_MIN;
    return MaxSumBSTUtil(root, maxsum).currmax;
}
  
// Driver code
int main()
{
    struct Node* root = new Node(5);
    root->left = new Node(14);
    root->right = new Node(3);
    root->left->left = new Node(6);
    root->right->right = new Node(7);
    root->left->left->left = new Node(9);
    root->left->left->right = new Node(1);
  
    cout << MaxSumBST(root);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG
{
      
// Binary tree node
static class Node 
{
    Node left;
    Node right;
    int data;
  
    Node(int data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
};
  
// Information stored in every
// node during bottom up traversal
static class Info 
{
  
    // Max Value in the subtree
    int max;
  
    // Min value in the subtree
    int min;
  
    // If subtree is BST
    boolean isBST;
  
    // Sum of the nodes of the sub-tree
    // rooted under the current node
    int sum;
  
    // Max sum of BST found till now
    int currmax;
      
    Info(int m,int mi,boolean is,int su,int cur)
    {
        max = m;
        min = mi;
        isBST = is;
        sum = su;
        currmax = cur;
    }
    Info(){}
};
  
static class INT
{
    int a;
}
  
// Returns information about subtree such as
// subtree with the maximum sum which is also a BST
static Info MaxSumBSTUtil( Node root, INT maxsum)
{
    // Base case
    if (root == null)
        return new Info( Integer.MIN_VALUE, 
                        Integer.MAX_VALUE, true, 0, 0 );
  
    // If current node is a leaf node then
    // return from the function and store
    // information about the leaf node
    if (root.left == null && root.right == null)
    {
        maxsum.a = Math.max(maxsum.a, root.data);
        return new Info( root.data, root.data, 
                        true, root.data, maxsum.a );
    }
  
    // Store information about the left subtree
    Info L = MaxSumBSTUtil(root.left, maxsum);
  
    // Store information about the right subtree
    Info R = MaxSumBSTUtil(root.right, maxsum);
  
    Info BST=new Info();
  
    // If the subtree rooted under the current node
    // is a BST
    if (L.isBST && R.isBST && L.max < root.data && 
                               R.min > root.data)
    {
  
        BST.max = Math.max(root.data, Math.max(L.max, R.max));
        BST.min = Math.min(root.data, Math.min(L.min, R.min));
  
        maxsum.a = Math.max(maxsum.a, R.sum + root.data + L.sum);
        BST.sum = R.sum + root.data + L.sum;
  
        // Update the current maximum sum
        BST.currmax = maxsum.a;
  
        BST.isBST = true;
        return BST;
    }
  
    // If the whole tree is not a BST then
    // update the current maximum sum
    BST.isBST = false;
    BST.currmax = maxsum.a;
    BST.sum = R.sum + root.data + L.sum;
  
    return BST;
}
  
// Function to return the maximum
// sum subtree which is also a BST
static int MaxSumBST( Node root)
{
    INT maxsum = new INT();
    maxsum.a = Integer.MIN_VALUE;
    return MaxSumBSTUtil(root, maxsum).currmax;
}
  
// Driver code
public static void main(String args[])
{
    Node root = new Node(5);
    root.left = new Node(14);
    root.right = new Node(3);
    root.left.left = new Node(6);
    root.right.right = new Node(7);
    root.left.left.left = new Node(9);
    root.left.left.right = new Node(1);
  
    System.out.println( MaxSumBST(root));
}
}
  
// This code is contributed by Arnab Kundu

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG
{
      
// Binary tree node
public class Node 
{
    public Node left;
    public Node right;
    public int data;
  
    public Node(int data)
    {
        this.data = data;
        this.left = null;
        this.right = null;
    }
};
  
// Information stored in every
// node during bottom up traversal
public class Info 
{
  
    // Max Value in the subtree
    public int max;
  
    // Min value in the subtree
    public int min;
  
    // If subtree is BST
    public bool isBST;
  
    // Sum of the nodes of the sub-tree
    // rooted under the current node
    public int sum;
  
    // Max sum of BST found till now
    public int currmax;
      
    public Info(int m,int mi,bool s,int su,int cur)
    {
        max = m;
        min = mi;
        isBST = s;
        sum = su;
        currmax = cur;
    }
    public Info(){}
};
  
public class INT
{
    public int a;
}
  
// Returns information about subtree such as
// subtree with the maximum sum which is also a BST
static Info MaxSumBSTUtil( Node root, INT maxsum)
{
    // Base case
    if (root == null)
        return new Info( int.MinValue, 
                        int.MaxValue, true, 0, 0 );
  
    // If current node is a leaf node then
    // return from the function and store
    // information about the leaf node
    if (root.left == null && root.right == null)
    {
        maxsum.a = Math.Max(maxsum.a, root.data);
        return new Info( root.data, root.data, 
                        true, root.data, maxsum.a );
    }
  
    // Store information about the left subtree
    Info L = MaxSumBSTUtil(root.left, maxsum);
  
    // Store information about the right subtree
    Info R = MaxSumBSTUtil(root.right, maxsum);
  
    Info BST = new Info();
  
    // If the subtree rooted under the current node
    // is a BST
    if (L.isBST && R.isBST && L.max < root.data && 
                            R.min > root.data)
    {
  
        BST.max = Math.Max(root.data, Math.Max(L.max, R.max));
        BST.min = Math.Min(root.data, Math.Min(L.min, R.min));
  
        maxsum.a = Math.Max(maxsum.a, R.sum + root.data + L.sum);
        BST.sum = R.sum + root.data + L.sum;
  
        // Update the current maximum sum
        BST.currmax = maxsum.a;
  
        BST.isBST = true;
        return BST;
    }
  
    // If the whole tree is not a BST then
    // update the current maximum sum
    BST.isBST = false;
    BST.currmax = maxsum.a;
    BST.sum = R.sum + root.data + L.sum;
  
    return BST;
}
  
// Function to return the maximum
// sum subtree which is also a BST
static int MaxSumBST( Node root)
{
    INT maxsum = new INT();
    maxsum.a = int.MinValue;
    return MaxSumBSTUtil(root, maxsum).currmax;
}
  
// Driver code
public static void Main(String []args)
{
    Node root = new Node(5);
    root.left = new Node(14);
    root.right = new Node(3);
    root.left.left = new Node(6);
    root.right.right = new Node(7);
    root.left.left.left = new Node(9);
    root.left.left.right = new Node(1);
  
    Console.WriteLine( MaxSumBST(root));
}
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Output:

10


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.