题目描述:
给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。
一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。
思路先出来,我的第一想法是,开一个全局map,和一个max记录出现次数最多元素和的次数是多少次。然后遍历每个结点,得出每个结点的元素和,存入HashMap里面,key存的是元素和,value存的是此元素和出现的次数,在这么过程中,如果某个元素和出现的次数大于max,那么将其赋值给max。
这样,第一个循环走完我们就将 元素和以及元素和出现次数对存进了map里。
下面只需要找到 map里面value 等于max 的所有元素和,放入ArrayList中,再存进数组里即可。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
Map<Integer,Integer> map = new HashMap<>(); //key存的是元素和,value是此元素和出现的次数
int max = 0;
public int[] findFrequentTreeSum(TreeNode root) {
getNums(root);
List<Integer> list = new ArrayList<>();
for(Map.Entry<Integer,Integer> entry : map.entrySet())
{
if(entry.getValue() == max)
{
list.add(entry.getKey());
}
}
int[] ans = new int[list.size()];
for(int i = 0;i < list.size(); i++)
{
ans[i] = list.get(i);
}
return ans;
}
public int getNums(TreeNode root)
{
if(root == null)
return 0;
int sum = root.val + getNums(root.left) + getNums(root.right);
map.put(sum,map.getOrDefault(sum,0) + 1);
max = Math.max(map.get(sum),max);
return sum;
}
}
对于java新手,我解释一下代码HashMap.entrySet()得到的是一个HashSet,
Set<Map.Entry<Integer,Integer>> set = new HashSet<>();
Set里面存地值是Map.Entry<Integer,Integer>
所以遍历Map就用这个操作:Map.Entry<Integer,Integer> entry : map.entrySet()
每个循环取到的实体是Map.Entry<Integer,Integer>
map.getOrDefault(sum,0)的意思是,如果map里面有key值sum,我们就取出它对应的value,
如果没有sum这个key值,就将0作为其输出,源码如下:
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))? v: defaultValue);
}