刷题的日常-出现次数最多的子树元素和

76 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情

刷题的日常-2022年12月22号

一天一题,保持脑子清爽

出现次数最多的子树元素和

来自leetcode的 508 题,题意如下:

给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。

一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。

示例1: image.png

输入: root = [5,2,-3]
输出: [2,-3,4]

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给一棵二叉树
  • 要求统计二叉树中相同值 的节点元素
  • 获取出现次数最多的元素
  • 将这些出现次数最多的值进行相加

做题思路

统计次数最多的很简单,就是遍历二叉树就可以了。通过递归进行统计,遍历的过程中用Map记录节点出现的次数,统计完成之后获取最大值,然后将这些最大值返回即可,步骤如下:

  • 开辟一个map进行记录
  • 对树进行递归
  • 递归过程需要返回子树的汇总结果
  • 将子树的汇总结果加上当前节点的值放入map中
  • 递归完成之后我们就得到了所有子树的汇总值
  • 遍历Map,拿到最大值
  • 然后将最大值的数据放进结果集当中
  • 返回结果

代码实现

代码实现如下:

public class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    public int[] findFrequentTreeSum(TreeNode root) {
        findFrequentTreeSum00(root);
        List<Integer> tmp = new ArrayList<>();
        int max = Integer.MIN_VALUE;
        for (Map.Entry<Integer, Integer> item : map.entrySet()) {
            Integer value = item.getValue();
            if (max > value) {
                continue;
            }
            if (max < value) {
                tmp.clear();
                max = value;
            }
            tmp.add(item.getKey());
        }
        int[] result = new int[tmp.size()];
        for (int i = 0; i < tmp.size(); i++) {
            result[i] = tmp.get(i);
        }
        return result;
    }
    private int findFrequentTreeSum00(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int left = findFrequentTreeSum00(root.left);
        int right = findFrequentTreeSum00(root.right);
        int sum = left + right + root.val;
        map.put(sum, map.computeIfAbsent(sum, o -> 0) + 1);
        return sum;
    }
}