Most Frequent Subtree Sum
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.
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.
简单的说,就是给定一个子树,求出其出现频率最高子树值的大小(这里的子树值指的是其节点值加上它的子节点的值,子节点的值递归)。
解法:
小编用的方法是HashMap,即以子树的Sum值做Key,而Sum值出现的次数做Value。
过程如下:
1. 先递归求出所有子树的Sum值和其出现的次数,并加入到HashMap中。
2. 将HashMap排序
3. 返回Value值最大的一组Key。
其中,第2点并不是说直接对HashMap排序,毕竟,HashMap中并没有提供sort方法,但是,List里有这个方法,所以我们可以把HashMap中的entrySet加到List中,然后再排序。
附代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
class Solution {
private HashMap<Integer,Integer> map ;
public Solution(){
map = new HashMap<>();
}
public int[] findFrequentTreeSum(TreeNode root) {
if(root == null)
return new int[]{};
setSubTreeSum(root);
//将map.entrySet转化为list并排序
List<Map.Entry<Integer,Integer>> list = new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());
// System.out.println("map.size:"+map.size());
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());//降序
}
});
int cnt = list.get(0).getValue();//最高的次数
int[] values = new int[list.size()];
int i;//数组长度
for(i = 0 ; i < list.size() ; i ++){
if(list.get(i).getValue() == cnt)//与最高计数次数相等,则记录,否则break;
values[i] = list.get(i).getKey();
else
break;
}
values = Arrays.copyOf(values, i);
return values;
}
public int setSubTreeSum(TreeNode root){
if(root == null)
return 0;
//返回本身的val+左右儿子的val
int valSum = root.val+setSubTreeSum(root.left) + setSubTreeSum(root.right);
// System.out.println("valsum:"+valSum);
if(!map.containsKey(valSum))
map.put(valSum, 1);
else
map.put(valSum, map.get(valSum)+1);
return valSum;
}
}