Most Frequent Subtree Sum

medium tree dfs hash map

Problem

Given the root of a binary tree, return the most frequent subtree sum — the sum of all node values rooted at a given node, including the node itself. If multiple sums tie, return all of them.

Inputtree = [5, 2, -3]
Output[2, -3, 4]
Subtree sums: leaf 2 → 2, leaf −3 → −3, root → 4. All three appear once, so all win.

from collections import Counter

def find_frequent_tree_sum(root):
    counts = Counter()

    def dfs(node):
        if not node:
            return 0
        s = node.val + dfs(node.left) + dfs(node.right)
        counts[s] += 1
        return s

    dfs(root)
    if not counts:
        return []
    top = max(counts.values())
    return [s for s, c in counts.items() if c == top]
function findFrequentTreeSum(root) {
  const counts = new Map();
  function dfs(node) {
    if (!node) return 0;
    const s = node.val + dfs(node.left) + dfs(node.right);
    counts.set(s, (counts.get(s) || 0) + 1);
    return s;
  }
  dfs(root);
  if (!counts.size) return [];
  const top = Math.max(...counts.values());
  return [...counts].filter(([, c]) => c === top).map(([s]) => s);
}
class Solution {
    Map<Integer, Integer> counts = new HashMap<>();
    int top = 0;

    public int[] findFrequentTreeSum(TreeNode root) {
        dfs(root);
        List<Integer> ans = new ArrayList<>();
        for (Map.Entry<Integer, Integer> e : counts.entrySet()) {
            if (e.getValue() == top) ans.add(e.getKey());
        }
        return ans.stream().mapToInt(i -> i).toArray();
    }

    private int dfs(TreeNode n) {
        if (n == null) return 0;
        int s = n.val + dfs(n.left) + dfs(n.right);
        counts.merge(s, 1, Integer::sum);
        top = Math.max(top, counts.get(s));
        return s;
    }
}
vector<int> findFrequentTreeSum(TreeNode* root) {
    unordered_map<int, int> counts;
    int top = 0;
    function<int(TreeNode*)> dfs = [&](TreeNode* n) -> int {
        if (!n) return 0;
        int s = n->val + dfs(n->left) + dfs(n->right);
        top = max(top, ++counts[s]);
        return s;
    };
    dfs(root);
    vector<int> ans;
    for (auto& [k, v] : counts) if (v == top) ans.push_back(k);
    return ans;
}
Time: O(n) Space: O(n)