求出现频率最高的子树值

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值