Most Frequent Subtree Sum

Updated on 19 June, 2025
Most Frequent Subtree Sum header image

Problem Statement

We are given the root of a binary tree and are tasked to find the most frequent subtree sum. The subtree sum for a node is defined as the overall sum of all nodes within the subtree, including the node itself. The goal is to calculate these sums for all subtrees in the binary tree, and identify which sum(s) appear most frequently. If more than one sum appears the same maximum number of times, all those sums should be returned in any order.

Examples

Example 1

Input:

root = [5,2,-3]

Output:

[2,-3,4]

Example 2

Input:

root = [5,2,-5]

Output:

[2]

Constraints

  • The number of nodes in the tree is in the range [1, 104].
  • -105 <= Node.val <= 105

Approach and Intuition

  1. The first step involves calculating the subtree sum for every node in the binary tree. We can achieve this through a recursive post-order traversal (left-right-root). In this traversal, the sum of a node is computed as the sum of its value and the sums of its left and right children.
  2. As we compute these sums, we can use a dictionary (or hash map) to keep a count of how many times each sum occurs.
  3. Once all sums have been computed and their frequencies tallied, the next task is identifying the sums with the maximum frequency. This requires examining the values in our frequency dictionary to find the highest frequency.
  4. Collect and return all sums that match this maximum frequency. These are the most frequent subtree sums. Depending on the values and structure of the binary tree, this could be one sum or multiple sums.

Example Walk-through:

  • For root = [5,2,-3]:

    • The sum of the subtree rooted at node 2 is just 2 (no children).
    • The sum of the subtree rooted at node -3 is -3 (no children).
    • The sum of the subtree rooted at node 5 (including its children) is 5 + 2 + (-3) = 4.
    • Here, the sums 2, -3, and 4 each appear once, thus they all are the most frequent sums. So the output is [2, -3, 4].
  • For root = [5,2,-5]:

    • The subtree rooted at node 2 sums to 2.
    • The subtree rooted at node -5 sums to -5.
    • The sum for the subtree of the root node 5 becomes 5 + 2 + (-5) = 2.
    • Here, the sum 2 appears twice (once at node 2 and once for the entire tree rooted at node 5), making it the most frequent subtree sum. Thus, the output is [2].

Solutions

  • C++
  • Java
  • JavaScript
  • Python
cpp
class Solution {
public:
    int calculateSum(TreeNode* node, unordered_map<int, int>& sumCounts, int& highestFrequency) {
        if (!node) return 0;

        int leftSum = calculateSum(node->left, sumCounts, highestFrequency);
        int rightSum = calculateSum(node->right, sumCounts, highestFrequency);

        int totalSum = node->val + leftSum + rightSum;

        sumCounts[totalSum]++;
        highestFrequency = max(highestFrequency, sumCounts[totalSum]);
        return totalSum;
    }
    
    vector<int> mostFrequentSum(TreeNode* root) {
        unordered_map<int, int> sumCounts;
        int highestFrequency = 0;

        calculateSum(root, sumCounts, highestFrequency);

        vector<int> result;
        for (auto& pair : sumCounts) {
            if (pair.second == highestFrequency) {
                result.push_back(pair.first);
            }
        }

        return result;
    }
};

This solution finds the most frequent subtree sums in a binary tree using C++. The process involves two main functions:

  1. calculateSum: This recursive function computes the total sum of each subtree originating from a given node.

    • It returns the sum of the node's value, its left subtree sum, and its right subtree sum.
    • Each computed sum is recorded into an unordered map sumCounts which keeps track of the frequency of each sum.
    • The function updates the highestFrequency variable whenever a new maximum frequency is encountered.
  2. mostFrequentSum: This is the main function called with the root of the tree.

    • It initializes an empty map sumCounts to store the frequency of each sum and an integer highestFrequency to keep track of the most frequent sum count.
    • It calls calculateSum to populate these structures.
    • After computing all sums, it iterates through the sumCounts map to gather all sums that occur with the highest frequency into the result vector.

The solution efficiently computes and retrieves the sums using depth-first search through recursive calls combined with hashing (via unordered_map) to track frequencies and retrieve the most frequent sums. The use of a map ensures efficient lookups, insertions, and frequency tracking, which makes the solution robust for large and complex tree structures.

java
class Solution {
    private HashMap<Integer, Integer> frequencyMap = new HashMap<>();
    private Integer highestFrequency = 0;
    
    private int calculateTreeSum(TreeNode node) {
        if (node == null) {
            return 0;
        }
        
        // Calculate subtree sums recursively
        int leftSum = calculateTreeSum(node.left);
        int rightSum = calculateTreeSum(node.right);

        // Current node sum calculation
        int totalSum = node.val + leftSum + rightSum;
        
        // Update frequency map
        frequencyMap.put(totalSum, frequencyMap.getOrDefault(totalSum, 0) + 1);
        highestFrequency = Math.max(highestFrequency, frequencyMap.get(totalSum));
        return totalSum;
    }
    
    public int[] findFrequentTreeSum(TreeNode node) {
        calculateTreeSum(node);
        
        List<Integer> frequentSums = new ArrayList<>(); 
        for (Map.Entry<Integer, Integer> entry : frequencyMap.entrySet()) {
            if (entry.getValue().equals(highestFrequency)) {
                frequentSums.add(entry.getKey());
            }
        }
        
        int[] result = new int[frequentSums.size()];
        for (int i = 0; i < frequentSums.size(); i++) {
            result[i] = frequentSums.get(i);
        }
        
        return result;
    }
}

In the provided solution for the "Most Frequent Subtree Sum" problem in Java, the approach largely revolves around tree traversal and hashmap utilization. Understand the mechanism with these points:

  • A private hashmap, frequencyMap, stores Sum frequencies from different subtrees.

  • A private integer, highestFrequency, maintains the record of the maximum frequency encountered.

  • Calculate the sum of nodes in all subtrees with a recursive helper function calculateTreeSum(TreeNode node), which performs:

    • Base case checking: if node is null, return 0.
    • Recursive calls for left and right subtree sums.
    • Computation of subtree sum for the current node and updating frequencyMap.
    • Persistent update of highestFrequency with maximum value from frequencyMap.
  • The method findFrequentTreeSum(TreeNode node) starts the traversal and calculation:

    • Calls calculateTreeSum method to populate frequencyMap.
    • Iterates through frequencyMap to identify sums occurring with highestFrequency.
    • Collects these sums into a list, then converts and returns them as an array of integers.

This code leverages efficient maps for frequency counting and selective gathering based on calculation results, making it both scalable and straightforward. Use this understanding to handle similar problems dealing with recursive data analysis in trees, especially when frequency of occurrence is a required output.

js
let frequencyOfSums = {};
let maximumFrequency = 0;

let calculateTreeSum = (node) => {
    if (!node) {
        return 0;
    }

    let sumLeft = calculateTreeSum(node.left);
    let sumRight = calculateTreeSum(node.right);

    let totalSum = node.val + sumLeft + sumRight;
    
    frequencyOfSums[totalSum] = (frequencyOfSums[totalSum] ?? 0) + 1;
    maximumFrequency = Math.max(maximumFrequency, frequencyOfSums[totalSum]);
    return totalSum;
}

let getFrequentTreeSum = function(root) {
    frequencyOfSums = {};
    maximumFrequency = 0;
    
    calculateTreeSum(root);
    
    let frequentSums = [];
    for (let sum in frequencyOfSums) {
        if (frequencyOfSums[sum] === maximumFrequency) {
            frequentSums.push(sum);
        }
    }

    return frequentSums;
};

This solution addresses the problem of finding the most frequent subtree sum in a binary tree using JavaScript. The approach involves two primary functions:

  • calculateTreeSum(node): This recursive function computes the sum of all values in the current subtree rooted at node. It uses a postorder traversal to first calculate sums of left and right subtrees, combines these with the value of the current node, and then updates a global object frequencyOfSums that keeps track of how often each sum occurs. Additionally, it updates the maximumFrequency to keep track of the highest frequency of any sum.

  • getFrequentTreeSum(root): This function initializes the data structures and calls calculateTreeSum to fill in the frequencies of sums. After computing these frequencies, it iterates over frequencyOfSums to collect all sums that occur at the maximum frequency.

By calling getFrequentTreeSum with the root of the tree, you receive an array of the most frequent subtree sums. This method efficiently maps subtree sums to their frequencies and then identifies the highest frequency sums to solve the problem.

python
class Solution:    
    def mostFrequentTreeSum(self, node: Optional[TreeNode]) -> List[int]:
        sum_count = {}
        highest_count = 0
        
        def calculate_tree_sum(node) -> int:
            if not node:
                return 0

            # Calculate sums of left and right children
            left_sum = calculate_tree_sum(node.left)
            right_sum = calculate_tree_sum(node.right)

            # Sum up the current node's value with its children's sums
            total_sum = node.val + left_sum + right_sum

            sum_count[total_sum] = sum_count.get(total_sum, 0) + 1
            highest_count = max(highest_count, sum_count[total_sum])
            return total_sum
        
        # Compute the sum for each subtree
        calculate_tree_sum(node)
        frequent_sums = []
        for s, count in sum_count.items():
            if count == highest_count:
                frequent_sums.append(s)
        
        return frequent_sums

This Python solution addresses the problem of finding the most frequent subtree sums in a binary tree. It defines a Solution class with a method mostFrequentTreeSum, which takes the root of a binary tree as input and returns a list of the most frequently occurring subtree sums.

  • Initialize sum_count dictionary to record frequencies of each subtree sum.
  • highest_count variable tracks the highest frequency of any sum.

The core functionality is implemented in the nested calculate_tree_sum function, which recursively calculates the sum of values in each subtree:

  1. Base case: if the node is None, the sum is 0.
  2. Recursively calculate the sum for the left and right children.
  3. The total sum at the current node is the value of the node plus the sums of its left and right subtrees.
  4. Update sum_count with the calculated total_sum of the current subtree.
  5. Update highest_count if the current sum's frequency exceeds it.
  6. Return the total_sum for the current subtree.

After computing subtree sums for all nodes:

  • Iterate through sum_count.
  • Collect all sums that have a frequency equal to highest_count.

The method finally returns the list of sums that occurred most frequently, effectively identifying the most common sum patterns within the tree's subtrees. This solution efficiently groups and tracks subtree sums, determining the most frequent occurrences in a single pass through the tree's nodes.

Comments

No comments yet.