持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
前言
今天的题目为中等,题目的意思可能会比较难理解,但是只要自己动手去试一下实例中的结果是怎么得到的,也就能够理解过程,题目就简单的使用深度优先搜索获取结点和,然后利用哈希表统计结果出现的次数即可。
每日一题
今天的题目是 508. 出现次数最多的子树元素和,难度为中等
-
给你一个二叉树的根结点 root ,请返回出现次数最多的子树元素和。如果有多个元素出现的次数相同,返回所有出现次数最多的子树元素和(不限顺序)。
-
一个结点的 「子树元素和」 定义为以该结点为根的二叉树上所有结点的元素之和(包括结点本身)。
示例 1:
输入: root = [5,2,-3]
输出: [2,-3,4]
示例 2:
输入: root = [5,2,-5]
输出: [2]
提示:
- 节点数在 [1, 104] 范围内
- -105 <= Node.val <= 105
题解
深度优先搜索
题目的关键点在于,子树元素和 这个概念,子树元素和 代表当前整棵树,每一个结点它和它子节点的元素和。
比如说一颗拥有三个结点的树:
那么他的三个 子树元素和 就分别为 5+2+-3,2 和 -3 这三个数,然后题目需要出现次数最多的那一个,对于上面这颗树来说,三个 子树元素和 出现的值各不相同,次数都是一次,所以答案就返回三个值的数组
在比如说
这个数的 子树元素和 就是 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;
};