leetcode刷题记录-508. 出现次数最多的子树元素和

144 阅读1分钟

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

前言

今天的题目为中等,题目的意思可能会比较难理解,但是只要自己动手去试一下实例中的结果是怎么得到的,也就能够理解过程,题目就简单的使用深度优先搜索获取结点和,然后利用哈希表统计结果出现的次数即可。

每日一题

今天的题目是 508. 出现次数最多的子树元素和,难度为中等

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

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

 

示例 1:

image.png

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

示例 2:

image.png

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

 

提示:

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

题解

深度优先搜索

题目的关键点在于,子树元素和 这个概念,子树元素和 代表当前整棵树,每一个结点它和它子节点的元素和。

比如说一颗拥有三个结点的树:

image.png

那么他的三个 子树元素和 就分别为 5+2+-3,2 和 -3 这三个数,然后题目需要出现次数最多的那一个,对于上面这颗树来说,三个 子树元素和 出现的值各不相同,次数都是一次,所以答案就返回三个值的数组

在比如说

image.png

这个数的 子树元素和 就是 5+-5+2,2和-5,在这其中,2 这个值出现了两次,所以出现次数最多的就只有2这一个值。

所以,我们需要先利用一个方法,去获取每一个结点的 子树元素和,然后用一个哈希表去保存,最后只需要查找哈希表中值最大的那个数就好了

使用深度优先遍历去获取每一个节点的 子树元素和,并且在每一次保存到哈希表的时候维护一个最大值

最后只需要去遍历哈希表,将val为最大值的key存入一个数组就好了。

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function findFrequentTreeSum(root: TreeNode | null): number[] {
    const map = new Map();
    let maxCount = 0;

    const dfs = (node: TreeNode | null): number => {
        if (!node) {
            return 0;
        }
        const sum = node.val + dfs(node.left) + dfs(node.right);
        map.set(sum, (map.get(sum) || 0) + 1);
        if (maxCount < map.get(sum)) {
            maxCount = map.get(sum);
        }
        return sum;
    }

    dfs(root);
    const list: any[] = [];
    for (const [key, val] of map.entries()) {
        if (val === maxCount) {
            list.push(key);
        }
    }
    return list;
};

image.png