刷完LeetCode题库——508. 出现次数最多的子树元素和

105 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

题目详情

LeetCode题库序号 508. 出现次数最多的子树元素和 ,难度为 中等

Tag : 「DFS」、「哈希表」

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

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

示例 1:

image.png

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

示例 2:

image.png

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

提示:

  • 节点数在 [1,104][1, 10^4] 范围内
  • 105 <=Node.val<=105-10^5 <= Node.val <= 10^5

深度优先搜索(DFS)

题解思路:

这道题目是典型的深度优先搜索的题目,因为你可以设想,我想要知道根节点的元素和,你必须要知道它左子树的根节点的元素和,和右子树根节点的元素和,三个累加在一起才是根节点的元素和。这时你想要知道左子树的根节点的元素和,你必须根据向上述情况一样。重复这个过程。不断的拆解成子问题。只有到达叶子节点时,就是它的终止条件。所以根据这个思路,将深度优先搜索过程中的元素和记录在map中。最后比较后返回。即可得到答案。具体可以看代码。

题解代码

class Solution {
    private int maxCnt = 0;

    Map<Integer, Integer> map = new HashMap<>();

    public int[] findFrequentTreeSum(TreeNode root) {
        dfs(root);
        List<Integer> array = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            int sum = entry.getKey();
            int num = entry.getValue();
            if (maxCnt ==  num) {
                array.add(sum);
            }
        }
        
        int[] ans = new int[array.size()];
        for (int i = 0; i < array.size(); i++) {
            ans[i] = array.get(i);
        }
        
        return ans;
    }

    private int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }

        int sum = node.val + dfs(node.left) + dfs(node.right);
        map.put(sum, map.getOrDefault(sum, 0) + 1);
        maxCnt = Math.max(maxCnt, map.get(sum));
        return sum;
    }
}

结尾

我的"刷完LeetCode题库"系列文章的第 No.508 序号的题目,本次刷题之旅系列开始于 2022-06-12,因为LeetCode上部分是有锁题,我自己的目标是将先把所有不带锁的题目刷完。自己能够通过这次刷题之旅勉励自己,并且提升逻辑思维能力。这个系列的文章就是会见证我自己的一个成长过程!

思路虽然不是最优的,但是我会尽我所能!

为了让我自己的刷题之旅不中断,我特地建立了相关的仓库,来记录我自己的刷题之旅。 github.com/jackpan123/…