Skip to content

Commit c316da9

Browse files
committed
Added Q508
1 parent 4f16aa4 commit c316da9

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
id: most-frequent-subtree-sum
3+
title: Most Frequent Subtree Sum
4+
sidebar_label: 0508-Most-Frequent-Subtree-Sum
5+
tags:
6+
- Tree
7+
- Depth-First Search
8+
- Hash Table
9+
- Binary Tree
10+
description: "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."
11+
---
12+
13+
## Problem
14+
15+
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.
16+
17+
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).
18+
19+
### Examples
20+
21+
**Example 1:**
22+
23+
**Input:** `root = [5,2,-3]`
24+
**Output:** `[2,-3,4]`
25+
**Explanation:** The subtree sums are:
26+
- Sum of the subtree rooted at node `5`: 4 (5 + 2 - 3)
27+
- Sum of the subtree rooted at node `2`: 2
28+
- Sum of the subtree rooted at node `-3`: -3
29+
The most frequent subtree sums are [2, -3, 4], occurring once each.
30+
31+
**Example 2:**
32+
33+
**Input:** `root = [5,2,-5]`
34+
**Output:** `[2]`
35+
**Explanation:** The subtree sums are:
36+
- Sum of the subtree rooted at node `5`: 2 (5 + 2 - 5)
37+
- Sum of the subtree rooted at node `2`: 2
38+
- Sum of the subtree rooted at node `-5`: -5
39+
The most frequent subtree sum is 2, occurring twice.
40+
41+
### Constraints
42+
43+
- The number of nodes in the tree is in the range `[1, 10^4]`.
44+
- `-10^5 <= Node.val <= 10^5`
45+
46+
---
47+
48+
## Approach
49+
50+
To solve this problem, we need to calculate the sum of all nodes for each subtree and count the frequency of each sum. Finally, we return the sums that have the highest frequency.
51+
52+
### Steps:
53+
54+
1. Use a hash table (dictionary) to store the frequency of each subtree sum.
55+
2. Traverse the tree using depth-first search (DFS) to calculate the sum of each subtree.
56+
3. For each node, calculate the subtree sum and update the frequency in the hash table.
57+
4. Determine the maximum frequency and collect all sums that have this frequency.
58+
5. Return the list of sums with the highest frequency.
59+
60+
### Solution
61+
62+
#### Java Solution
63+
64+
```java
65+
import java.util.ArrayList;
66+
import java.util.HashMap;
67+
import java.util.List;
68+
import java.util.Map;
69+
70+
public class TreeNode {
71+
int val;
72+
TreeNode left;
73+
TreeNode right;
74+
TreeNode(int x) { val = x; }
75+
}
76+
77+
class Solution {
78+
private Map<Integer, Integer> countMap = new HashMap<>();
79+
private int maxCount = 0;
80+
81+
public int[] findFrequentTreeSum(TreeNode root) {
82+
if (root == null) return new int[0];
83+
dfs(root);
84+
List<Integer> result = new ArrayList<>();
85+
for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
86+
if (entry.getValue() == maxCount) {
87+
result.add(entry.getKey());
88+
}
89+
}
90+
return result.stream().mapToInt(i -> i).toArray();
91+
}
92+
93+
private int dfs(TreeNode node) {
94+
if (node == null) return 0;
95+
int sum = node.val + dfs(node.left) + dfs(node.right);
96+
countMap.put(sum, countMap.getOrDefault(sum, 0) + 1);
97+
maxCount = Math.max(maxCount, countMap.get(sum));
98+
return sum;
99+
}
100+
}
101+
```
102+
### C++ Solution
103+
104+
```cpp
105+
#include <vector>
106+
#include <unordered_map>
107+
#include <algorithm>
108+
using namespace std;
109+
110+
struct TreeNode {
111+
int val;
112+
TreeNode *left;
113+
TreeNode *right;
114+
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
115+
};
116+
117+
class Solution {
118+
public:
119+
vector<int> findFrequentTreeSum(TreeNode* root) {
120+
unordered_map<int, int> countMap;
121+
int maxCount = 0;
122+
vector<int> result;
123+
dfs(root, countMap, maxCount);
124+
for (const auto& entry : countMap) {
125+
if (entry.second == maxCount) {
126+
result.push_back(entry.first);
127+
}
128+
}
129+
return result;
130+
}
131+
132+
private:
133+
int dfs(TreeNode* node, unordered_map<int, int>& countMap, int& maxCount) {
134+
if (node == nullptr) return 0;
135+
int sum = node->val + dfs(node->left, countMap, maxCount) + dfs(node->right, countMap, maxCount);
136+
countMap[sum]++;
137+
maxCount = max(maxCount, countMap[sum]);
138+
return sum;
139+
}
140+
};
141+
```
142+
### Python
143+
144+
```python
145+
from collections import defaultdict
146+
from typing import List, Optional
147+
148+
# Definition for a binary tree node.
149+
class TreeNode:
150+
def __init__(self, val=0, left=None, right=None):
151+
self.val = val
152+
self.left = left
153+
self.right = right
154+
155+
class Solution:
156+
def findFrequentTreeSum(self, root: Optional[TreeNode]) -> List[int]:
157+
if not root:
158+
return []
159+
160+
def dfs(node):
161+
if not node:
162+
return 0
163+
total = node.val + dfs(node.left) + dfs(node.right)
164+
count[total] += 1
165+
self.maxCount = max(self.maxCount, count[total])
166+
return total
167+
168+
count = defaultdict(int)
169+
self.maxCount = 0
170+
dfs(root)
171+
return [s for s in count if count[s] == self.maxCount]
172+
```
173+
### Complexity Analysis
174+
**Time Complexity:** O(n)
175+
>Reason: Each node is visited once during the DFS traversal.
176+
177+
### Space Complexity: O(n)
178+
>Reason: The space required to store the subtree sums and their frequencies in the hash table is proportional to the number of nodes.
179+
180+
### References
181+
LeetCode Problem: Most Frequent Subtree Sum

0 commit comments

Comments
 (0)