Skip to content
Related Articles

Related Articles

Improve Article

Most Frequent Subtree Sum from a given Binary Tree

  • Difficulty Level : Medium
  • Last Updated : 07 Jan, 2021

Given a Binary Tree, the task is to find the most frequent subtree sum that can be obtained by considering every node of the given tree as the root of the subtree. If more than one such sums exist, then print all of them.

Examples:

Input:
                 5
              /   \
            2   -4 

Output: 2 -4 3
Explanation:
The sum of nodes considering 5 as the root of subtree is 5 + 2 – 4 = 3.
The sum of nodes considering 2 as the root of subtree is 2 = 2.
The sum of nodes considering -4 as the root of subtree is -4 = -4.
Since all the sums have same frequency, print all the sum.

Input:
              4
           /   \
         2    -4 



Output: 2
Explanation:
The sum of nodes considering 4 as the root of subtree is 4 + 2 – 4 = 2.
The sum of nodes considering 2 as the root of subtree is 2 = 2.
The sum of nodes considering -4 as the root of subtree is -4 = -4.
Since, sum 2 has maximum frequency ( = 2). Hence, print the value 2.

Approach: The idea to use the DFS Traversal for the given tree to solve the given problem. Follow the below steps to solve the problem:

  • Create two auxiliary Hash Map M and F where M is a set of integer keys and corresponding lists, and F will store the frequency of each number.
  • Perform the DFS Traversal for the given tree and do the following:
    • If the node is NULL, return 0.
    • Initialize variables left and right that stores the value of the sum of nodes left and right subtree of the current node.
    • Find the sum of currentNode.value + left + right store it in a variable totalSum.
    • Now update the frequency of totalSum in the map F.
    • Update the frequency of the value F[totalSum] as totalSum in the map M.
    • Return the value to totalSum from the current recursive function.
  • After the above steps, print all the element of the list M.rbegin().

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to print the vector
void printVector(vector<int> v)
{
    // Traverse vector c
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
}
  
// TreeNode class
class TreeNode {
public:
    int val;
    TreeNode *left, *right;
  
    // Constructor
    TreeNode(int data)
    {
        val = data;
        left = NULL;
        right = NULL;
    }
};
  
// Function to insert node in the
// binary tree
void insert(TreeNode** root, int val)
{
    // Initialize Queue
    queue<TreeNode*> q;
  
    // Push the node root
    q.push(*root);
  
    // While Q.size() is there
    while (q.size()) {
  
        // Get the front node
        TreeNode* temp = q.front();
        q.pop();
  
        // If left is NULL
        if (!temp->left) {
            if (val)
                temp->left = new TreeNode(val);
            else
                temp->left = new TreeNode(0);
            return;
        }
        else {
            q.push(temp->left);
        }
  
        // If right is NULL
        if (!temp->right) {
            if (val)
                temp->right = new TreeNode(val);
            else
                temp->right = new TreeNode(0);
            return;
        }
        else {
            q.push(temp->right);
        }
    }
}
  
// Function to make the tree from
// given node values
TreeNode* buildTree(vector<int> v)
{
    TreeNode* root = new TreeNode(v[0]);
  
    // Traverse and insert node
    for (int i = 1; i < v.size(); i++) {
        insert(&root, v[i]);
    }
    return root;
}
  
// Utility function to find subtree
// sum with highest frequency of a
// particular node
int findsubTreeSumUtil(
    TreeNode* node, map<int,
                        vector<int> >& mpp,
    map<int, int>& frequency)
{
    if (!node)
        return 0;
  
    // Recur for the left subtree
    int left = findsubTreeSumUtil(
        node->left, mpp, frequency);
  
    // Recur for the right subtree
    int right = findsubTreeSumUtil(
        node->right, mpp, frequency);
  
    // Stores sum of nodes of a subtree
    int totalSum = node->val + left + right;
  
    // Update the frequency
    if (!frequency.count(totalSum)) {
        mpp[1].push_back(totalSum);
        frequency[totalSum] = 1;
    }
    else {
        frequency[totalSum]++;
        mpp[frequency[totalSum]].push_back(totalSum);
    }
  
    // Return the total sum
    return totalSum;
}
  
// Function to find subtree sum with
// highest frequency of given tree
void findsubTreeSum(TreeNode* root)
{
    // Store list of nodes attached to
    // a particular node and frequency
    // of visited nodes
    map<int, vector<int> > mpp;
    map<int, int> frequency;
  
    // Base Case
    if (!root) {
        printVector({});
        return;
    }
  
    // DFS function call
    findsubTreeSumUtil(root, mpp, frequency);
  
    // Print the vector
    printVector(mpp.rbegin()->second);
}
  
// Driver Code
int main()
{
    // Given nodes of the tree
    vector<int> v = { 5, 2, -4 };
  
    // Function call to build the tree
    TreeNode* tree = buildTree(v);
  
    // Function Call
    findsubTreeSum(tree);
  
    return 0;
}
Output:
2 -4 3

Time Complexity: O(N)
Auxiliary Space: O(N)

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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :