LeetCode Solutions

508. Most Frequent Subtree Sum

Time: $O(n)$

Space: $O(n)$

			

class Solution {
 public:
  vector<int> findFrequentTreeSum(TreeNode* root) {
    vector<int> ans;
    unordered_map<int, int> count;
    int maxCount = 0;

    sumDownFrom(root, count);

    for (const auto& [_, freq] : count)
      maxCount = max(maxCount, freq);

    for (const auto& [sum, freq] : count)
      if (freq == maxCount)
        ans.push_back(sum);

    return ans;
  }

 private:
  int sumDownFrom(TreeNode* root, unordered_map<int, int>& count) {
    if (root == nullptr)
      return 0;

    const int sum = root->val + sumDownFrom(root->left, count) +
                    sumDownFrom(root->right, count);
    ++count[sum];
    return sum;
  }
};
			

class Solution {
  public int[] findFrequentTreeSum(TreeNode root) {
    List<Integer> ans = new ArrayList<>();
    Map<Integer, Integer> count = new HashMap<>();
    int maxCount = 0;

    sumDownFrom(root, count);

    for (final int freq : count.values())
      maxCount = Math.max(maxCount, freq);

    for (final int sum : count.keySet())
      if (count.get(sum) == maxCount)
        ans.add(sum);

    return ans.stream().mapToInt(Integer::intValue).toArray();
  }

  private int sumDownFrom(TreeNode root, Map<Integer, Integer> count) {
    if (root == null)
      return 0;

    final int sum = root.val + sumDownFrom(root.left, count) + sumDownFrom(root.right, count);
    count.merge(sum, 1, Integer::sum);
    return sum;
  }
}
			

class Solution:
  def findFrequentTreeSum(self, root: Optional[TreeNode]) -> List[int]:
    if not root:
      return []

    count = Counter()

    def dfs(root: Optional[TreeNode]) -> int:
      if not root:
        return 0

      summ = root.val + dfs(root.left) + dfs(root.right)
      count[summ] += 1
      return summ

    dfs(root)
    maxFreq = max(count.values())
    return [summ for summ in count if count[summ] == maxFreq]