Given the root
of a binary tree, return the most frequent subtree sum. If there is a tie, return all the values with the highest frequency in any order.
The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself).
Example 1:
Input: root = [5,2,-3] Output: [2,-3,4]
Example 2:
Input: root = [5,2,-5] Output: [2]
Constraints:
[1, 104]
.-105 <= Node.val <= 105
Given the root of a binary tree, return the most frequent subtree sum. If there is a tie, return all the values with the highest frequency in any order. The subtree sum of a node is the sum of all node values in the subtree rooted at that node.
The optimal solution involves a depth-first search (DFS) combined with a hash map (or dictionary). We'll traverse the tree, calculating the subtree sum at each node. We'll use a hash map to keep track of the frequency of each subtree sum encountered.
Algorithm:
Depth-First Search (DFS): A recursive DFS function will traverse the tree. For each node, it recursively calculates the subtree sums of its left and right subtrees. Then, it adds the node's value to these subtree sums to get the total subtree sum for the current node.
Hash Map (Frequency Counting): A hash map (like HashMap
in Rust, unordered_map
in C++, dict
in Python, or Map
in Java/TypeScript) stores the frequency of each subtree sum encountered. For each calculated subtree sum, we increment its count in the hash map.
Finding the Most Frequent Sum(s): After the DFS is complete, we iterate through the hash map to find the sum(s) with the highest frequency. We return a list of these sums.
from collections import Counter
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
count = Counter()
def dfs(node):
if not node:
return 0
left_sum = dfs(node.left)
right_sum = dfs(node.right)
subtree_sum = left_sum + right_sum + node.val
count[subtree_sum] += 1
return subtree_sum
dfs(root)
max_freq = max(count.values())
return [s for s, freq in count.items() if freq == max_freq]
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
Map<Integer, Integer> count = new HashMap<>();
public int[] findFrequentTreeSum(TreeNode root) {
dfs(root);
int maxFreq = 0;
for (int freq : count.values()) {
maxFreq = Math.max(maxFreq, freq);
}
List<Integer> result = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
if (entry.getValue() == maxFreq) {
result.add(entry.getKey());
}
}
return result.stream().mapToInt(Integer::intValue).toArray();
}
private int dfs(TreeNode node) {
if (node == null) {
return 0;
}
int leftSum = dfs(node.left);
int rightSum = dfs(node.right);
int subtreeSum = leftSum + rightSum + node.val;
count.put(subtreeSum, count.getOrDefault(subtreeSum, 0) + 1);
return subtreeSum;
}
}
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
std::map<int, int> count;
std::vector<int> findFrequentTreeSum(TreeNode* root) {
dfs(root);
int maxFreq = 0;
for (auto const& [key, val] : count) {
maxFreq = std::max(maxFreq, val);
}
std::vector<int> result;
for (auto const& [key, val] : count) {
if (val == maxFreq) {
result.push_back(key);
}
}
return result;
}
int dfs(TreeNode* node) {
if (node == nullptr) {
return 0;
}
int leftSum = dfs(node->left);
int rightSum = dfs(node->right);
int subtreeSum = leftSum + rightSum + node->val;
count[subtreeSum]++;
return subtreeSum;
}
};
(Other languages like Javascript, Go, Rust would follow a similar structure, adapting the data structures and syntax accordingly.)
This detailed explanation, along with the provided code examples in multiple languages, should clarify the solution to the problem. Remember to adapt the code to your specific environment and coding style.