Find largest subtree sum in a tree

Last Updated : 24 Jul, 2026

Given the root of a binary tree, find the maximum subtree sum among all possible subtrees and return that sum.

A subtree of a node consists of the node itself and all of its descendants.

Examples:  

Input: root[] = [10, 8, 2, 3, 5, N, N]

blobid1_1778816962

Output: 28
Explanation:
As all the tree elements are positive, the largest subtree sum is equal to sum of all tree elements.

Input: root[] = [1, -2, 3, 4, 5, -6, 2]

blobid0_1778816938

Output: 7
Explanation: Subtree with largest sum is :

blobid2_1778817079

The whole tree sum is also 7.

Try It Yourself
redirect icon

[Naive Approach] Recompute Subtree Sum for Every Node - O(n²) Time and O(h) Space

The idea is to treat every node as the root of a subtree. For each node, recursively calculate the sum of all nodes in its subtree and compare it with the maximum subtree sum found so far. Since the subtree sums are computed independently for every node, the same nodes are visited multiple times, resulting in redundant calculations.

C++
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;
  
    Node(int x) {
      data = x;
      left = right = nullptr;
    }
};

  // Returns the sum of the subtree rooted at 'root'.
    int subtreeSum(Node* root) {
        if (root == nullptr)
            return 0;

        return root->data + subtreeSum(root->left)
                          + subtreeSum(root->right);
    }

    // Traverses all nodes and updates the maximum subtree sum.
    void dfs(Node* root, int &ans) {
        if (root == nullptr)
            return;

        ans = max(ans, subtreeSum(root));

        dfs(root->left, ans);
        dfs(root->right, ans);
    }

    int maxSubtreeSum(Node* root) {
        if (root == nullptr)
            return 0;

        int ans = INT_MIN;
        dfs(root, ans);

        return ans;
    }



int main() {
  
    // Representation of the given tree
    //          1
    //        /   \
    //      -2     3
    //      / \   / \
    //     4   5 -6  2
    Node* root = new Node(1);
    root->left = new Node(-2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(-6);
    root->right->right = new Node(2);

    cout << maxSubtreeSum(root);
    return 0;
}
Java
class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = right = null;
    }
}

class Main {

    // Returns the sum of the subtree rooted at 'root'.
    static int subtreeSum(Node root) {
        if (root == null)
            return 0;

        return root.data + subtreeSum(root.left)
                         + subtreeSum(root.right);
    }

    // Traverses all nodes and updates the maximum subtree sum.
    static void dfs(Node root, int[] ans) {
        if (root == null)
            return;

        ans[0] = Math.max(ans[0], subtreeSum(root));

        dfs(root.left, ans);
        dfs(root.right, ans);
    }

    static int maxSubtreeSum(Node root) {
        if (root == null)
            return 0;

        int[] ans = {Integer.MIN_VALUE};
        dfs(root, ans);

        return ans[0];
    }

    public static void main(String[] args) {

        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        System.out.print(maxSubtreeSum(root));
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None


# Returns the sum of the subtree rooted at 'root'.
def subtreeSum(root):
    if root is None:
        return 0

    return (root.data +
            subtreeSum(root.left) +
            subtreeSum(root.right))


# Traverses all nodes and updates the maximum subtree sum.
def dfs(root, ans):
    if root is None:
        return

    ans[0] = max(ans[0], subtreeSum(root))

    dfs(root.left, ans)
    dfs(root.right, ans)


def maxSubtreeSum(root):
    if root is None:
        return 0

    ans = [float('-inf')]
    dfs(root, ans)

    return ans[0]


# Representation of the given tree
#          1
#        /   \
#      -2     3
#      / \   / \
#     4   5 -6  2
root = Node(1)
root.left = Node(-2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(-6)
root.right.right = Node(2)

print(maxSubtreeSum(root))
C#
using System;

class Node
{
    public int data;
    public Node left, right;

    public Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GFG
{
    // Returns the sum of the subtree rooted at 'root'.
    static int subtreeSum(Node root)
    {
        if (root == null)
            return 0;

        return root.data + subtreeSum(root.left)
                         + subtreeSum(root.right);
    }

    // Traverses all nodes and updates the maximum subtree sum.
    static void dfs(Node root, ref int ans)
    {
        if (root == null)
            return;

        ans = Math.Max(ans, subtreeSum(root));

        dfs(root.left, ref ans);
        dfs(root.right, ref ans);
    }

    static int maxSubtreeSum(Node root)
    {
        if (root == null)
            return 0;

        int ans = int.MinValue;
        dfs(root, ref ans);

        return ans;
    }

    static void Main()
    {
        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        Console.Write(maxSubtreeSum(root));
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Returns the sum of the subtree rooted at 'root'.
function subtreeSum(root) {
    if (root === null)
        return 0;

    return root.data + subtreeSum(root.left)
                     + subtreeSum(root.right);
}

// Traverses all nodes and updates the maximum subtree sum.
function dfs(root, ans) {
    if (root === null)
        return;

    ans[0] = Math.max(ans[0], subtreeSum(root));

    dfs(root.left, ans);
    dfs(root.right, ans);
}

function maxSubtreeSum(root) {
    if (root === null)
        return 0;

    let ans = [-Infinity];
    dfs(root, ans);

    return ans[0];
}

// Representation of the given tree
//          1
//        /   \
//      -2     3
//      / \   / \
//     4   5 -6  2
let root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(-6);
root.right.right = new Node(2);

console.log(maxSubtreeSum(root));

Output
7

[Expected Approach - 1] Using Recursion (Postorder Traversal) - O(n) Time and O(h) Space

The idea is to calculate the subtree sum for every node using postorder traversal. In postorder traversal, we first visit the left subtree, then the right subtree, and finally the current node. This ensures that the subtree sums of both children are already known before processing the current node.

For every node, recursively find the sum of its left and right subtrees. Then, add these sums to the current node's value to get the subtree sum rooted at that node. While computing these sums, keep track of the largest subtree sum found so far.

Consider the following binary tree:

file

The tree is processed in postorder (Left -> Right -> Root): 4 -> 5 -> -2 -> -6 -> 2 -> 3 -> 1

Subtree sums are computed while returning from recursion:

  • Node 4 -> Leaf node, so subtree sum = 4.
  • Node 5 -> Leaf node, so subtree sum = 5.
  • Node -6 -> Leaf node, so subtree sum = -6.
  • Node 2 -> Leaf node, so subtree sum = 2.
  • Node -2 -> Add left and right subtree sums: -2 + 4 + 5 = 7.
  • Node 3 -> Add left and right subtree sums: 3 + (-6) + 2 = -1.
  • Node 1 -> Add left and right subtree sums: 1 + 7 + (-1) = 7.

The subtree rooted at node -2 has the largest sum, which is 7. Hence, the largest subtree sum is 7.

C++
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;
  
    Node(int x) {
      data = x;
      left = right = nullptr;
    }
};

// Helper function to find largest
// subtree sum recursively.
int findLargestSubtreeSumUtil(Node* root, int& ans) {
  
    // If current node is null then
    // return 0 to parent node.
    if (root == nullptr)     
        return 0;
    
    // Subtree sum rooted at current node.
    int currSum = root->data + 
      findLargestSubtreeSumUtil(root->left, ans)
      + findLargestSubtreeSumUtil(root->right, ans);

    // Update answer if current subtree
    // sum is greater than answer so far.
    ans = max(ans, currSum);

    // Return current subtree sum to
    // its parent node.
    return currSum;
}

int maxSubtreeSum(Node* root) {
  
    // If tree does not exist, 
    // then answer is 0.
    if (root == nullptr)     
        return 0;
    
    int ans = INT_MIN;

    findLargestSubtreeSumUtil(root, ans);

    return ans;
}

int main() {
  
    // Representation of the given tree
    //          1
    //        /   \
    //      -2     3
    //      / \   / \
    //     4   5 -6  2
    Node* root = new Node(1);
    root->left = new Node(-2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(-6);
    root->right->right = new Node(2);

    cout << maxSubtreeSum(root);
    return 0;
}
Java
class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = right = null;
    }
}

class GFG {

    // Helper function to find largest
    // subtree sum recursively.
    static int findLargestSubtreeSumUtil(Node root, int[] ans) {

        // If current node is null then
        // return 0 to parent node.
        if (root == null)
            return 0;

        // Subtree sum rooted at current node.
        int currSum = root.data
                + findLargestSubtreeSumUtil(root.left, ans)
                + findLargestSubtreeSumUtil(root.right, ans);

        // Update answer if current subtree
        // sum is greater than answer so far.
        ans[0] = Math.max(ans[0], currSum);

        // Return current subtree sum to
        // its parent node.
        return currSum;
    }

    static int maxSubtreeSum(Node root) {

        // If tree does not exist,
        // then answer is 0.
        if (root == null)
            return 0;

        int[] ans = {Integer.MIN_VALUE};

        findLargestSubtreeSumUtil(root, ans);

        return ans[0];
    }

    public static void main(String[] args) {

        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        System.out.print(maxSubtreeSum(root));
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None


# Helper function to find largest
# subtree sum recursively.
def findLargestSubtreeSumUtil(root, ans):

    # If current node is null then
    # return 0 to parent node.
    if root is None:
        return 0

    # Subtree sum rooted at current node.
    currSum = (root.data +
               findLargestSubtreeSumUtil(root.left, ans) +
               findLargestSubtreeSumUtil(root.right, ans))

    # Update answer if current subtree
    # sum is greater than answer so far.
    ans[0] = max(ans[0], currSum)

    # Return current subtree sum to
    # its parent node.
    return currSum


def maxSubtreeSum(root):

    # If tree does not exist,
    # then answer is 0.
    if root is None:
        return 0

    ans = [float('-inf')]

    findLargestSubtreeSumUtil(root, ans)

    return ans[0]


# Representation of the given tree
#          1
#        /   \
#      -2     3
#      / \   / \
#     4   5 -6  2
root = Node(1)
root.left = Node(-2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(-6)
root.right.right = Node(2)

print(maxSubtreeSum(root))
C#
using System;

class Node
{
    public int data;
    public Node left, right;

    public Node(int x)
    {
        data = x;
        left = right = null;
    }
}

class GFG
{
    // Helper function to find largest
    // subtree sum recursively.
    static int findLargestSubtreeSumUtil(Node root, ref int ans)
    {
        // If current node is null then
        // return 0 to parent node.
        if (root == null)
            return 0;

        // Subtree sum rooted at current node.
        int currSum = root.data
            + findLargestSubtreeSumUtil(root.left, ref ans)
            + findLargestSubtreeSumUtil(root.right, ref ans);

        // Update answer if current subtree
        // sum is greater than answer so far.
        ans = Math.Max(ans, currSum);

        // Return current subtree sum to
        // its parent node.
        return currSum;
    }

    static int maxSubtreeSum(Node root)
    {
        // If tree does not exist,
        // then answer is 0.
        if (root == null)
            return 0;

        int ans = int.MinValue;

        findLargestSubtreeSumUtil(root, ref ans);

        return ans;
    }

    static void Main()
    {
        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        Console.Write(maxSubtreeSum(root));
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Helper function to find largest
// subtree sum recursively.
function findLargestSubtreeSumUtil(root, ans) {

    // If current node is null then
    // return 0 to parent node.
    if (root === null)
        return 0;

    // Subtree sum rooted at current node.
    let currSum = root.data
        + findLargestSubtreeSumUtil(root.left, ans)
        + findLargestSubtreeSumUtil(root.right, ans);

    // Update answer if current subtree
    // sum is greater than answer so far.
    ans[0] = Math.max(ans[0], currSum);

    // Return current subtree sum to
    // its parent node.
    return currSum;
}

function maxSubtreeSum(root) {

    // If tree does not exist,
    // then answer is 0.
    if (root === null)
        return 0;

    let ans = [-Infinity];

    findLargestSubtreeSumUtil(root, ans);

    return ans[0];
}

// Representation of the given tree
//          1
//        /   \
//      -2     3
//      / \   / \
//     4   5 -6  2
let root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(-6);
root.right.right = new Node(2);

console.log(maxSubtreeSum(root));

Output
7

[Expected Approach - 2] Using BFS (Level Order Traversal) - O(n) Time and O(n) Space

The idea is to first perform a level order traversal (BFS) and store the nodes level by level. Then, process the stored levels in reverse order (from bottom to top).

For each node, compute its subtree sum by adding its own value and the subtree sums of its left and right children, which have already been calculated. While computing these sums, keep updating the maximum subtree sum.

Consider the following binary tree:

file

Step 1: Store Nodes Level Wise

Using BFS, store the nodes at each level.

  • Level 0 : [1]
  • Level 1 : [-2, 3]
  • Level 2 : [4, 5, -6, 2]

Now process the levels from bottom to top.

Step 2: Process Level 2

These are leaf nodes, so their subtree sums are their own values.

  • subtreeSum[4] = 4
  • subtreeSum[5] = 5
  • subtreeSum[-6] = -6
  • subtreeSum[2] = 2

Maximum subtree sum = 5

Step 3: Process Level 1

  • For node -2: subtreeSum[-2] = -2 + 4 + 5 = 7
  • Maximum subtree sum = 7
  • For node 3: subtreeSum[3] = 3 + (-6) + 2 = -1
  • Maximum subtree sum remains 7.

Step 4: Process Level 0

  • For the root 1: subtreeSum[1] = 1 + 7 + (-1) = 7
  • Maximum subtree sum remains 7.

Final Answer:

The subtree sums are:

  • 4 -> 4
  • 5 -> 5
  • -6 -> -6
  • 2 -> 2
  • -2 -> 7
  • 3 -> -1
  • 1 -> 7

Hence, the largest subtree sum is 7.

C++
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int x) {
        data = x;
        left = nullptr;
        right = nullptr;
    }
};

int maxSubtreeSum(Node* root) {
  
    // Base case when tree is empty
    if (root == nullptr)
        return 0;

    int ans = INT_MIN;

    queue<Node*> q;

    // Vector of Vector for storing
    // nodes at a particular level
    vector<vector<Node*> > levels;

    // Map for storing sum of subtree 
    // rooted at a particular node
    unordered_map<Node*, int> subtreeSum;

    // Push root to the queue
    q.push(root);

    while (!q.empty()) {
      
        int n = q.size();

        vector<Node*> level;
      
        while (n--) {
            Node* node = q.front();
          
            // Push current node to current
          	// level vector
            level.push_back(node);

            // Add left & right child of node
          	// in the queue
            if (node->left)
                q.push(node->left);
            if (node->right)
                q.push(node->right);

            q.pop();
        }

        // add current level to levels
      	// vector
        levels.push_back(level);
    }

    // Traverse all levels from bottom
  	//most level to top most level
    for (int i = levels.size() - 1; i >= 0; i--) {

        for (auto e : levels[i]) {
          
            // add value of current node
            subtreeSum[e] = e->data;

            // If node has left child, add the subtree sum
            // of subtree rooted at left child
            if (e->left)
                subtreeSum[e] += subtreeSum[e->left];

            // If node has right child, add the subtree sum
            // of subtree rooted at right child
            if (e->right)
                subtreeSum[e] += subtreeSum[e->right];

            // update ans to maximum of ans and sum of
            // subtree rooted at current node
            ans = max(ans, subtreeSum[e]);
        }
    }
  
    return ans;
}

int main() {
  
    // Representation of the given tree
    //          1
    //        /   \
    //      -2     3
    //      / \   / \
    //     4   5 -6  2
    Node* root = new Node(1);
    root->left = new Node(-2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(-6);
    root->right->right = new Node(2);

    cout << maxSubtreeSum(root) << endl;

    return 0;
}
Java
import java.util.*;

class Node {
    int data;
    Node left;
    Node right;

    Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {
  
    public static int maxSubtreeSum(Node root) {
  
        // Base case when tree is empty
        if (root == null)
            return 0;

        int ans = Integer.MIN_VALUE;

        // Queue for level order traversal
        Queue<Node> q = new LinkedList<>();

        // List of List for storing
        // nodes at a particular level
        List<List<Node>> levels = new ArrayList<>();

        // Map for storing sum of subtree 
        // rooted at a particular node
        HashMap<Node, Integer> subtreeSum = 
          					new HashMap<>();

        q.add(root);

        while (!q.isEmpty()) {
      
            int n = q.size();

            List<Node> level = new ArrayList<>();
      
            while (n-- > 0) {
                Node node = q.poll();
          
                // Push current node to current 
              	// level list
                level.add(node);

                // Add left & right child of node
              	// in the queue
                if (node.left != null)
                    q.add(node.left);
                if (node.right != null)
                    q.add(node.right);
            }

            // add current level to
          	// levels list
            levels.add(level);
        }

        // Traverse all levels from bottom 
      	// most level to top most level
        for (int i = levels.size() - 1; i >= 0; i--) {
            for (Node e : levels.get(i)) {
          
                // add value of current node
                subtreeSum.put(e, e.data);

                // If node has left child, add the subtree sum
                // of subtree rooted at left child
                if (e.left != null)
                    subtreeSum.put(e, subtreeSum.get(e)
                                   + subtreeSum.get(e.left));

                // If node has right child, add the subtree sum
                // of subtree rooted at right child
                if (e.right != null)
                    subtreeSum.put(e, subtreeSum.get(e)
                                   + subtreeSum.get(e.right));

                // update ans to maximum of ans and sum of
                // subtree rooted at current node
                ans = Math.max(ans, subtreeSum.get(e));
            }
        }
  
        return ans;
    }

    public static void main(String[] args) {
  
        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        System.out.println(maxSubtreeSum(root));
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

def maxSubtreeSum(root):
  
    # Base case when tree is empty
    if root is None:
        return 0

    ans = float('-inf')

    # Queue for level order
    # traversal
    q = []

    # List of List for storing
    # nodes at a particular level
    levels = []

    # Dictionary for storing sum of subtree 
    # rooted at a particular node
    subtreeSum = {}

    # Push root to the queue
    q.append(root)

    while q:
      
        n = len(q)

        level = []
      
        while n > 0:
            node = q.pop(0)
          
            # Push current node to current
            # level list
            level.append(node)

            # Add left & right child of node
            # in the queue
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

            n -= 1

        # add current level to 
        # levels list
        levels.append(level)

    # Traverse all levels from bottom most level to top
    # most level
    for i in range(len(levels) - 1, -1, -1):

        for e in levels[i]:
          
            # add value of current node
            subtreeSum[e] = e.data

            # If node has left child, add the subtree sum
            # of subtree rooted at left child
            if e.left:
                subtreeSum[e] += subtreeSum[e.left]

            # If node has right child, add the subtree sum
            # of subtree rooted at right child
            if e.right:
                subtreeSum[e] += subtreeSum[e.right]

            # update ans to maximum of ans and sum of
            # subtree rooted at current node
            ans = max(ans, subtreeSum[e])
  
    return ans

if __name__ == "__main__":
  
    # Representation of the given tree
    #          1
    #        /   \
    #      -2     3
    #      / \   / \
    #     4   5 -6  2
    root = Node(1)
    root.left = Node(-2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)
    root.right.left = Node(-6)
    root.right.right = Node(2)

    print(maxSubtreeSum(root))
C#
using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {
    public static int maxSubtreeSum(Node root) {
  
        // Base case when tree is empty
        if (root == null)
            return 0;

        int ans = int.MinValue;

        // Queue for level order traversal
        Queue<Node> q = new Queue<Node>();

        // List of List for storing
        // nodes at a particular level
        List<List<Node>> levels = 
          					new List<List<Node>>();

        // Dictionary for storing sum of subtree 
        // rooted at a particular node
        Dictionary<Node, int> subtreeSum = 
          					new Dictionary<Node, int>();

        // Push root to the queue
        q.Enqueue(root);

        while (q.Count > 0) {
      
            int n = q.Count;

            List<Node> level = new List<Node>();
      
            while (n-- > 0) {
                Node node = q.Dequeue();
          
                // Push current node to current
              	// level list
                level.Add(node);

                // Add left & right child of node
              	// in the queue
                if (node.left != null)
                    q.Enqueue(node.left);
                if (node.right != null)
                    q.Enqueue(node.right);
            }

            // add current level to 
          	// levels list
            levels.Add(level);
        }

        // Traverse all levels from bottom 
      	// most level to top most level
        for (int i = levels.Count - 1; i >= 0; i--) {

            foreach (var e in levels[i]) {
          
                // add value of current node
                subtreeSum[e] = e.data;

                // If node has left child, add the subtree sum
                // of subtree rooted at left child
                if (e.left != null)
                    subtreeSum[e] += subtreeSum[e.left];

                // If node has right child, add the subtree sum
                // of subtree rooted at right child
                if (e.right != null)
                    subtreeSum[e] += subtreeSum[e.right];

                // update ans to maximum of ans and sum of
                // subtree rooted at current node
                ans = Math.Max(ans, subtreeSum[e]);
            }
        }
  
        return ans;
    }

    public static void Main() {
  
        // Representation of the given tree
        //          1
        //        /   \
        //      -2     3
        //      / \   / \
        //     4   5 -6  2
        Node root = new Node(1);
        root.left = new Node(-2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(-6);
        root.right.right = new Node(2);

        Console.WriteLine(maxSubtreeSum(root));
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

function maxSubtreeSum(root) {
  
    // Base case when tree is empty
    if (root === null)
        return 0;

    let ans = Number.NEGATIVE_INFINITY;

    // Queue for level order traversal
    const q = [];

    // Array of Array for storing
    // nodes at a particular level
    const levels = [];

    // Map for storing sum of subtree 
    // rooted at a particular node
    const subtreeSum = new Map();

    // Push root to the queue
    q.push(root);

    while (q.length > 0) {
      
        const n = q.length;

        const level = [];
      
        for (let i = 0; i < n; i++) {
            const node = q.shift();
          
            // Push current node to current 
            // level array
            level.push(node);

            // Add left & right child of node
            // in the queue
            if (node.left)
                q.push(node.left);
            if (node.right)
                q.push(node.right);
        }

        // add current level to levels array
        levels.push(level);
    }

    // Traverse all levels from bottom most level to top
    // most level
    for (let i = levels.length - 1; i >= 0; i--) {

        for (const e of levels[i]) {
          
            // add value of current node
            subtreeSum.set(e, e.data);

            // If node has left child, add the subtree sum
            // of subtree rooted at left child
            if (e.left)
                subtreeSum.set(e, subtreeSum.get(e) 
                		+ subtreeSum.get(e.left));

            // If node has right child, add the subtree sum
            // of subtree rooted at right child
            if (e.right)
                subtreeSum.set(e, subtreeSum.get(e) 
                		+ subtreeSum.get(e.right));

            // update ans to maximum of ans and sum of
            // subtree rooted at current node
            ans = Math.max(ans, subtreeSum.get(e));
        }
    }
  
    return ans;
}

// Driver code

// Representation of the given tree
//          1
//        /   \
//      -2     3
//      / \   / \
//     4   5 -6  2
const root = new Node(1);
root.left = new Node(-2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(-6);
root.right.right = new Node(2);

console.log(maxSubtreeSum(root));

Output
7
Comment