
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
- 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.
- As we compute these sums, we can use a dictionary (or hash map) to keep a count of how many times each sum occurs.
- 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.
- 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
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:
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.
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 integerhighestFrequency
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 theresult
vector.
- It initializes an empty map
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.
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 fromfrequencyMap
.
- Base case checking: if node is
The method
findFrequentTreeSum(TreeNode node)
starts the traversal and calculation:- Calls
calculateTreeSum
method to populatefrequencyMap
. - Iterates through
frequencyMap
to identify sums occurring withhighestFrequency
. - Collects these sums into a list, then converts and returns them as an array of integers.
- Calls
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.
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 atnode
. 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 objectfrequencyOfSums
that keeps track of how often each sum occurs. Additionally, it updates themaximumFrequency
to keep track of the highest frequency of any sum.getFrequentTreeSum(root)
: This function initializes the data structures and callscalculateTreeSum
to fill in the frequencies of sums. After computing these frequencies, it iterates overfrequencyOfSums
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.
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:
- Base case: if the node is
None
, the sum is 0. - Recursively calculate the sum for the left and right children.
- The total sum at the current node is the value of the node plus the sums of its left and right subtrees.
- Update
sum_count
with the calculatedtotal_sum
of the current subtree. - Update
highest_count
if the current sum's frequency exceeds it. - 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.
No comments yet.