-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathMostFrequentSubtreeSum508.java
110 lines (94 loc) · 3.05 KB
/
MostFrequentSubtreeSum508.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* Given the root of a tree, you are asked to find the most frequent subtree
* sum. 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). So
* what is the most frequent subtree sum value? If there is a tie, return all
* the values with the highest frequency in any order.
*
* Examples 1
* Input:
*
* 5
* / \
* 2 -3
* return [2, -3, 4], since all the values happen only once, return all of
* them in any order.
*
* Examples 2
* Input:
*
* 5
* / \
* 2 -5
* return [2], since 2 happens twice, however -5 only occur once.
*
* Note: You may assume the sum of values in any subtree is in the range of
* 32-bit signed integer.
*
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class MostFrequentSubtreeSum508 {
public int[] findFrequentTreeSum(TreeNode root) {
Map<Integer, Integer> sums = new HashMap<>();
if (root == null) return new int[0];
int[] cache = new int[1];
cache[0] = Integer.MIN_VALUE;
helper(root, sums, cache);
List<Integer> list = new ArrayList<>();
for (Map.Entry<Integer, Integer> e: sums.entrySet()) {
if (e.getValue().equals(cache[0])) {
list.add(e.getKey());
}
}
int[] res = new int[list.size()];
for (int i=0; i<list.size(); i++) res[i] = list.get(i);
return res;
}
private Integer helper(TreeNode n, Map<Integer, Integer> sums, int[] cache) {
if (n == null) return null;
Integer left = helper(n.left, sums, cache);
Integer right = helper(n.right, sums, cache);
int sum = ((left == null) ? 0 : left) + ((right == null) ? 0 : right) + n.val;
int t = sums.getOrDefault(sum, 0) + 1;
cache[0] = Math.max(cache[0], t);
sums.put(sum, t);
return sum;
}
public int[] findFrequentTreeSum2(TreeNode root) {
Map<Integer, Integer> map = new HashMap<>();
findFrequentTreeSum(root, map);
int freq = 0;
Set<Integer> sums = new HashSet<>();
for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
if (entry.getValue() == freq) {
sums.add(entry.getKey());
} else if (entry.getValue() > freq) {
freq = entry.getValue();
sums.clear();
sums.add(entry.getKey());
}
}
int[] res = new int[sums.size()];
int i = 0;
for (int n: sums) {
res[i++] = n;
}
return res;
}
public int findFrequentTreeSum(TreeNode root, Map<Integer, Integer> map) {
if (root == null) return 0;
int l = findFrequentTreeSum(root.left, map);
int r = findFrequentTreeSum(root.right, map);
int sum = l + r + root.val;
map.put(sum, map.getOrDefault(sum, 0) + 1);
return sum;
}
}