一、Description
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.(subtree sum of root:4 = 5 + 2 - 3)
Examples 2
Input:
5 / \ 2 -5
return [2], since 2 happens twice, however -5 only occur once.(subtree sum of root:2 = 5 + 2 - 5)
二、Analyzation
我首先定义了一个map和一个优先队列,Word的val用来存储每个结点的子树和,count表示子树和出现的次数。先通过递归函数将所有结点置为对应的子树和的值(从叶子结点开始往上递归),每次计算一个子树和就放进map中,并更新对应的次数,最后通过优先队列,将最上面的结点依次放入list中,只要当前出队的Word的count小于前一次出队的Word的count,说明子树和出现次数最多的Word已经全部放入list中,最后返回result数组即可。
三、Accepted code
class Word {
int val;
int count;
public Word(int val, int count) {
this.val = val;
this.count = count;
}
}
class Solution {
PriorityQueue<Word> queue = new PriorityQueue<>(new Comparator<Word>() {
@Override
public int compare(Word o1, Word o2) {
return o2.count - o1.count;
}
});
Map<Integer, Integer> map = new HashMap<>();
public int[] findFrequentTreeSum(TreeNode root) {
if (root == null) {
return new int[0];
}
help(root);
for (Integer i : map.keySet()) {
Word word = new Word(i, map.get(i));
queue.add(word);
}
List<Integer> list = new ArrayList<>();
while (!queue.isEmpty()) {
Word word = queue.poll();
list.add(word.val);
if (!queue.isEmpty() && queue.peek().count < word.count) {
break;
}
}
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
System.out.println(Arrays.toString(result));
return result;
}
public void help(TreeNode root) {
if (root.left != null) {
help(root.left);
}
if (root.right != null) {
help(root.right);
}
root.val += (root.left == null ? 0 : root.left.val) + (root.right == null ? 0 : root.right.val);
if (map.containsKey(root.val)) {
int value = map.get(root.val);
map.put(root.val, value + 1);
} else {
map.put(root.val, 1);
}
}
}