Skip to content

Commit b6ed089

Browse files
committedAug 20, 2017
refactor 508
1 parent efad02f commit b6ed089

File tree

2 files changed

+132
-57
lines changed

2 files changed

+132
-57
lines changed
 

‎src/main/java/com/fishercoder/solutions/_508.java

+93-41
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.util.*;
66

77
/**
8+
* 508. Most Frequent Subtree Sum
9+
*
810
* Given the root of a tree, you are asked to find the most frequent subtree sum.
911
* 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).
1012
* 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.
@@ -28,54 +30,104 @@
2830
*/
2931
public class _508 {
3032

31-
//my purely original but verbose solution
32-
public int[] findFrequentTreeSum(TreeNode root) {
33-
if (root == null) return new int[]{};
34-
35-
Map<TreeNode, Integer> map = new HashMap();
36-
postOrder(root, map);
37-
38-
Map<Integer, Integer> frequencyMap = new HashMap<>();
39-
for (Map.Entry entry : map.entrySet()) {
40-
frequencyMap.put((Integer) entry.getValue(), frequencyMap.getOrDefault(entry.getValue(), 0)+1);
41-
}
42-
43-
List<Map.Entry<Integer, Integer>> list = new LinkedList<>(frequencyMap.entrySet());
44-
Collections.sort(list, (o1, o2) -> (o2.getValue()).compareTo(o1.getValue()));
45-
46-
int mostFrequency = list.get(0).getValue();
47-
List<Integer> topFrequencyList = new ArrayList<>();
48-
topFrequencyList.add(list.get(0).getKey());
49-
int i = 1;
50-
while (i < list.size() && list.get(i).getValue() == mostFrequency) {
51-
topFrequencyList.add(list.get(i).getKey());
52-
i++;
33+
public static class Solution1 {
34+
//my purely original but verbose solution
35+
public int[] findFrequentTreeSum(TreeNode root) {
36+
if (root == null) return new int[]{};
37+
38+
Map<TreeNode, Integer> map = new HashMap();
39+
postOrder(root, map);
40+
41+
Map<Integer, Integer> frequencyMap = new HashMap<>();
42+
for (Map.Entry entry : map.entrySet()) {
43+
frequencyMap.put((Integer) entry.getValue(), frequencyMap.getOrDefault(entry.getValue(), 0) + 1);
44+
}
45+
46+
List<Map.Entry<Integer, Integer>> list = new LinkedList<>(frequencyMap.entrySet());
47+
Collections.sort(list, (o1, o2) -> (o2.getValue()).compareTo(o1.getValue()));
48+
49+
int mostFrequency = list.get(0).getValue();
50+
List<Integer> topFrequencyList = new ArrayList<>();
51+
topFrequencyList.add(list.get(0).getKey());
52+
int i = 1;
53+
while (i < list.size() && list.get(i).getValue() == mostFrequency) {
54+
topFrequencyList.add(list.get(i).getKey());
55+
i++;
56+
}
57+
58+
int[] result = new int[topFrequencyList.size()];
59+
for (int j = 0; j < topFrequencyList.size(); j++) {
60+
result[j] = topFrequencyList.get(j);
61+
}
62+
63+
return result;
5364
}
5465

55-
int[] result = new int[topFrequencyList.size()];
56-
for (int j = 0; j < topFrequencyList.size(); j++) {
57-
result[j] = topFrequencyList.get(j);
66+
private int postOrder(TreeNode root, Map<TreeNode, Integer> map) {
67+
int left = 0;
68+
int right = 0;
69+
if (root.left != null) {
70+
left = postOrder(root.left, map);
71+
}
72+
if (root.right != null) {
73+
right = postOrder(root.right, map);
74+
}
75+
if (root.left == null && root.right == null) {
76+
map.put(root, root.val);
77+
return root.val;
78+
}
79+
int sum = left + right + root.val;
80+
map.put(root, sum);
81+
return sum;
5882
}
59-
60-
return result;
6183
}
6284

63-
private int postOrder(TreeNode root, Map<TreeNode, Integer> map) {
64-
int left = 0;
65-
int right = 0;
66-
if (root.left != null) {
67-
left = postOrder(root.left, map);
85+
public static class Solution2 {
86+
//my 2nd purely original but verbose solution
87+
public int[] findFrequentTreeSum(TreeNode root) {
88+
Map<Integer, Integer> map = new HashMap<>();
89+
dfs(root, map);
90+
List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(map.entrySet());
91+
Collections.sort(entryList, (a, b) -> b.getValue() - a.getValue());
92+
List<Integer> list = new ArrayList<>();
93+
for (int i = 0; i < entryList.size(); i++) {
94+
if (list.size() == 0) {
95+
list.add(entryList.get(i).getKey());
96+
} else {
97+
if (map.get(list.get(0)) == entryList.get(i).getValue()) {
98+
list.add(entryList.get(i).getKey());
99+
} else {
100+
break;
101+
}
102+
}
103+
}
104+
int[] result = new int[list.size()];
105+
for (int i = 0; i < list.size(); i++) {
106+
result[i] = list.get(i);
107+
}
108+
return result;
68109
}
69-
if (root.right != null) {
70-
right = postOrder(root.right, map);
71-
}
72-
if (root.left == null && root.right == null) {
73-
map.put(root, root.val);
74-
return root.val;
110+
111+
private int dfs(TreeNode root, Map<Integer, Integer> map) {
112+
if (root == null) {
113+
return 0;
114+
}
115+
if (root.left == null && root.right == null) {
116+
map.put(root.val, map.getOrDefault(root.val, 0) + 1);
117+
return root.val;
118+
}
119+
int leftVal = 0;
120+
if (root.left != null) {
121+
leftVal = dfs(root.left, map);
122+
}
123+
int rightVal = 0;
124+
if (root.right != null) {
125+
rightVal = dfs(root.right, map);
126+
}
127+
int val = leftVal + rightVal + root.val;
128+
map.put(val, map.getOrDefault(val, 0) + 1);
129+
return val;
75130
}
76-
int sum = left + right + root.val;
77-
map.put(root, sum);
78-
return sum;
79131
}
80132

81133
//a more concise and space-efficient solution: https://discuss.leetcode.com/topic/77775/verbose-java-solution-postorder-traverse-hashmap-18ms
+39-16
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,71 @@
11
package com.fishercoder;
22

33
import com.fishercoder.common.classes.TreeNode;
4+
import com.fishercoder.common.utils.TreeUtils;
45
import com.fishercoder.solutions._508;
56
import org.junit.Before;
67
import org.junit.BeforeClass;
78
import org.junit.Test;
89

10+
import java.util.Arrays;
11+
912
import static org.junit.Assert.assertArrayEquals;
1013

1114
public class _508Test {
12-
private static _508 test;
15+
private static _508.Solution1 solution1;
16+
private static _508.Solution2 solution2;
1317
private static int[] expected;
1418
private static int[] actual;
1519
private static TreeNode root;
1620

1721
@BeforeClass
18-
public static void setup(){
19-
test = new _508();
22+
public static void setup() {
23+
solution1 = new _508.Solution1();
24+
solution2 = new _508.Solution2();
2025
}
2126

2227
@Before
23-
public void setupForEachTest(){
28+
public void setupForEachTest() {
2429
expected = new int[]{};
2530
actual = new int[]{};
2631
root = null;
2732
}
2833

2934
@Test
30-
public void test1(){
31-
root = new TreeNode(5);
32-
root.left = new TreeNode(2);
33-
root.right = new TreeNode(-3);
34-
expected = new int[]{2,-3,4};
35-
actual = test.findFrequentTreeSum(root);
36-
// assertArrayEquals(expected, actual);
35+
public void test1() {
36+
root = TreeUtils.constructBinaryTree(Arrays.asList(5, 2, -3));
37+
expected = new int[]{2, -3, 4};
38+
/**Since order does NOT matter, so I'll sort them and then compare*/
39+
Arrays.sort(expected);
40+
actual = solution1.findFrequentTreeSum(root);
41+
Arrays.sort(actual);
42+
assertArrayEquals(expected, actual);
43+
44+
actual = solution2.findFrequentTreeSum(root);
45+
Arrays.sort(actual);
46+
assertArrayEquals(expected, actual);
3747
}
3848

3949
@Test
40-
public void test2(){
41-
root = new TreeNode(5);
42-
root.left = new TreeNode(2);
43-
root.right = new TreeNode(-5);
50+
public void test2() {
51+
root = TreeUtils.constructBinaryTree(Arrays.asList(5, 2, -5));
4452
expected = new int[]{2};
45-
actual = test.findFrequentTreeSum(root);
53+
actual = solution1.findFrequentTreeSum(root);
54+
assertArrayEquals(expected, actual);
55+
56+
actual = solution2.findFrequentTreeSum(root);
57+
assertArrayEquals(expected, actual);
58+
}
59+
60+
@Test
61+
public void test3() {
62+
root = TreeUtils.constructBinaryTree(Arrays.asList(3, 1, 5, 0, 2, 4, 6, null, null, null, 3));
63+
TreeUtils.printBinaryTree(root);
64+
expected = new int[]{6};
65+
actual = solution1.findFrequentTreeSum(root);
66+
assertArrayEquals(expected, actual);
67+
68+
actual = solution2.findFrequentTreeSum(root);
4669
assertArrayEquals(expected, actual);
4770
}
4871
}

0 commit comments

Comments
 (0)