Skip to content

Commit 0226650

Browse files
authored
feat: add solutions to lc problem: No.0508 (doocs#3570)
No.0508.Most Frequent Subtree Sum
1 parent 9692656 commit 0226650

File tree

8 files changed

+221
-263
lines changed

8 files changed

+221
-263
lines changed

solution/0500-0599/0508.Most Frequent Subtree Sum/README.md

+75-87
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ tags:
5858

5959
<!-- solution:start -->
6060

61-
### 方法一
61+
### 方法一:哈希表 + DFS
62+
63+
我们可以使用一个哈希表 $\textit{cnt}$ 记录每个子树元素和出现的次数,然后使用深度优先搜索遍历整棵树,统计每个子树的元素和,并更新 $\textit{cnt}$。
64+
65+
最后,我们遍历 $\textit{cnt}$,找到所有出现次数最多的子树元素和。
66+
67+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点个数。
6268

6369
<!-- tabs:start -->
6470

@@ -72,19 +78,19 @@ tags:
7278
# self.left = left
7379
# self.right = right
7480
class Solution:
75-
def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
76-
def dfs(root):
81+
def findFrequentTreeSum(self, root: Optional[TreeNode]) -> List[int]:
82+
def dfs(root: Optional[TreeNode]) -> int:
7783
if root is None:
7884
return 0
79-
left, right = dfs(root.left), dfs(root.right)
80-
s = root.val + left + right
81-
counter[s] += 1
85+
l, r = dfs(root.left), dfs(root.right)
86+
s = l + r + root.val
87+
cnt[s] += 1
8288
return s
8389

84-
counter = Counter()
90+
cnt = Counter()
8591
dfs(root)
86-
mx = max(counter.values())
87-
return [k for k, v in counter.items() if v == mx]
92+
mx = max(cnt.values())
93+
return [k for k, v in cnt.items() if v == mx]
8894
```
8995

9096
#### Java
@@ -106,33 +112,26 @@ class Solution:
106112
* }
107113
*/
108114
class Solution {
109-
private Map<Integer, Integer> counter;
115+
private Map<Integer, Integer> cnt = new HashMap<>();
110116
private int mx;
111117

112118
public int[] findFrequentTreeSum(TreeNode root) {
113-
counter = new HashMap<>();
114-
mx = Integer.MIN_VALUE;
115119
dfs(root);
116-
List<Integer> res = new ArrayList<>();
117-
for (Map.Entry<Integer, Integer> entry : counter.entrySet()) {
118-
if (entry.getValue() == mx) {
119-
res.add(entry.getKey());
120+
List<Integer> ans = new ArrayList<>();
121+
for (var e : cnt.entrySet()) {
122+
if (e.getValue() == mx) {
123+
ans.add(e.getKey());
120124
}
121125
}
122-
int[] ans = new int[res.size()];
123-
for (int i = 0; i < res.size(); ++i) {
124-
ans[i] = res.get(i);
125-
}
126-
return ans;
126+
return ans.stream().mapToInt(i -> i).toArray();
127127
}
128128

129129
private int dfs(TreeNode root) {
130130
if (root == null) {
131131
return 0;
132132
}
133133
int s = root.val + dfs(root.left) + dfs(root.right);
134-
counter.put(s, counter.getOrDefault(s, 0) + 1);
135-
mx = Math.max(mx, counter.get(s));
134+
mx = Math.max(mx, cnt.merge(s, 1, Integer::sum));
136135
return s;
137136
}
138137
}
@@ -154,26 +153,26 @@ class Solution {
154153
*/
155154
class Solution {
156155
public:
157-
unordered_map<int, int> counter;
158-
int mx = 0;
159-
160156
vector<int> findFrequentTreeSum(TreeNode* root) {
161-
mx = INT_MIN;
157+
unordered_map<int, int> cnt;
158+
int mx = 0;
159+
function<int(TreeNode*)> dfs = [&](TreeNode* root) -> int {
160+
if (!root) {
161+
return 0;
162+
}
163+
int s = root->val + dfs(root->left) + dfs(root->right);
164+
mx = max(mx, ++cnt[s]);
165+
return s;
166+
};
162167
dfs(root);
163168
vector<int> ans;
164-
for (auto& entry : counter)
165-
if (entry.second == mx)
166-
ans.push_back(entry.first);
169+
for (const auto& [k, v] : cnt) {
170+
if (v == mx) {
171+
ans.push_back(k);
172+
}
173+
}
167174
return ans;
168175
}
169-
170-
int dfs(TreeNode* root) {
171-
if (!root) return 0;
172-
int s = root->val + dfs(root->left) + dfs(root->right);
173-
++counter[s];
174-
mx = max(mx, counter[s]);
175-
return s;
176-
}
177176
};
178177
```
179178
@@ -188,29 +187,26 @@ public:
188187
* Right *TreeNode
189188
* }
190189
*/
191-
func findFrequentTreeSum(root *TreeNode) []int {
192-
counter := make(map[int]int)
193-
mx := 0
194-
var dfs func(root *TreeNode) int
190+
func findFrequentTreeSum(root *TreeNode) (ans []int) {
191+
cnt := map[int]int{}
192+
var mx int
193+
var dfs func(*TreeNode) int
195194
dfs = func(root *TreeNode) int {
196195
if root == nil {
197196
return 0
198197
}
199198
s := root.Val + dfs(root.Left) + dfs(root.Right)
200-
counter[s]++
201-
if mx < counter[s] {
202-
mx = counter[s]
203-
}
199+
cnt[s]++
200+
mx = max(mx, cnt[s])
204201
return s
205202
}
206203
dfs(root)
207-
var ans []int
208-
for k, v := range counter {
204+
for k, v := range cnt {
209205
if v == mx {
210206
ans = append(ans, k)
211207
}
212208
}
213-
return ans
209+
return
214210
}
215211
```
216212

@@ -232,26 +228,22 @@ func findFrequentTreeSum(root *TreeNode) []int {
232228
*/
233229

234230
function findFrequentTreeSum(root: TreeNode | null): number[] {
235-
const map = new Map<number, number>();
236-
let max = 0;
237-
const dfs = (root: TreeNode | null) => {
238-
if (root == null) {
231+
const cnt = new Map<number, number>();
232+
let mx = 0;
233+
const dfs = (root: TreeNode | null): number => {
234+
if (!root) {
239235
return 0;
240236
}
241237
const { val, left, right } = root;
242-
const sum = val + dfs(left) + dfs(right);
243-
map.set(sum, (map.get(sum) ?? 0) + 1);
244-
max = Math.max(max, map.get(sum));
245-
return sum;
238+
const s = val + dfs(left) + dfs(right);
239+
cnt.set(s, (cnt.get(s) ?? 0) + 1);
240+
mx = Math.max(mx, cnt.get(s)!);
241+
return s;
246242
};
247243
dfs(root);
248-
const res = [];
249-
for (const [k, v] of map) {
250-
if (v === max) {
251-
res.push(k);
252-
}
253-
}
254-
return res;
244+
return Array.from(cnt.entries())
245+
.filter(([_, c]) => c === mx)
246+
.map(([s, _]) => s);
255247
}
256248
```
257249

@@ -279,33 +271,29 @@ function findFrequentTreeSum(root: TreeNode | null): number[] {
279271
use std::cell::RefCell;
280272
use std::collections::HashMap;
281273
use std::rc::Rc;
282-
impl Solution {
283-
fn dfs(
284-
root: &Option<Rc<RefCell<TreeNode>>>,
285-
map: &mut HashMap<i32, i32>,
286-
max: &mut i32,
287-
) -> i32 {
288-
if root.is_none() {
289-
return 0;
290-
}
291-
let node = root.as_ref().unwrap().borrow();
292-
let sum = node.val + Self::dfs(&node.left, map, max) + Self::dfs(&node.right, map, max);
293-
map.insert(sum, map.get(&sum).unwrap_or(&0) + 1);
294-
*max = (*max).max(map[&sum]);
295-
sum
296-
}
297274

275+
impl Solution {
298276
pub fn find_frequent_tree_sum(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
299-
let mut map = HashMap::new();
300-
let mut max = 0;
301-
let mut res = Vec::new();
302-
Self::dfs(&root, &mut map, &mut max);
303-
for (k, v) in map.into_iter() {
304-
if v == max {
305-
res.push(k);
277+
fn dfs(root: Option<Rc<RefCell<TreeNode>>>, cnt: &mut HashMap<i32, i32>) -> i32 {
278+
if let Some(node) = root {
279+
let l = dfs(node.borrow().left.clone(), cnt);
280+
let r = dfs(node.borrow().right.clone(), cnt);
281+
let s = l + r + node.borrow().val;
282+
*cnt.entry(s).or_insert(0) += 1;
283+
s
284+
} else {
285+
0
306286
}
307287
}
308-
res
288+
289+
let mut cnt = HashMap::new();
290+
dfs(root, &mut cnt);
291+
292+
let mx = cnt.values().cloned().max().unwrap_or(0);
293+
cnt.into_iter()
294+
.filter(|&(_, v)| v == mx)
295+
.map(|(k, _)| k)
296+
.collect()
309297
}
310298
}
311299
```

0 commit comments

Comments
 (0)