1161. 最大层内元素和
题目
给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。
请返回层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。
示例 1:
输入:root = [1,7,0,7,-8,null,null]
输出:2
解释:
第 1 层各元素之和为 1,
第 2 层各元素之和为 7 + 0 = 7,
第 3 层各元素之和为 7 + -8 = -1,
所以我们返回第 2 层的层号,它的层内元素之和最大。
示例 2:
输入:root = [989,null,10250,98693,-89388,null,null,null,-32127]
输出:2
分析
题目要求返回第n层之内元素之和最大的最小层数,自上而下,第一次遇到最大元素之和就是最小的层,使用广度优先遍历,一层一层向下。
如果使用深度优先,需要一个数组来维护每层元素之和,和树的深度
题解
广度优先遍历
class Solution {public int maxLevelSum(TreeNode root) {// 返回层内元素之和最大的层号,且是最小的层号// 广度优先遍历,一层一层向下,遇到最大值就记录层号(深度),返回最大值的层号,因为是从上向下遍历,如果没有更大值,那么当前的最大值就是最小层// 队列,保存每一层的节点,队列是动态的,只保存一层的节点Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);// 树的深度、初始最大值、最大值的深度int dept = 0;int max = Integer.MIN_VALUE;// 这个max要取最小值,初始不能为0,因为题目要求可以出现负数int max_dept = 0;// 广度优先,将每一层依次入队,并依次遍历这个节点的左右子节点,作为下一层的父节点while(!queue.isEmpty()){// 获取上一层节点的子节点数量,就是这一轮需要遍历的int size = queue.size();dept++;// 因为这不是递归,而是while循环,所以只有一个sum,初始时为0int sum = 0;for(int i = 0; i < size; i++){// 取出一个节点,计入sumTreeNode node = queue.poll();sum += node.val;// 将这个节点的左右子节点入队,用于下一层的遍历if(node.left != null){queue.offer(node.left);}if(node.right != null){queue.offer(node.right);}}// 自上而下,第一次遇到最大值就是最小的层号,不使用=>判断// 因为题目要求计算各层元素之和,所以每层遍历完再计算最大值if(sum > max){max = sum;max_dept = dept;}}return max_dept;}
}
深度优先遍历
class Solution {private List<Integer> sum = new ArrayList<>();public int maxLevelSum(TreeNode root) {// 广度优先,利用数组,数组长度为树的层数,数组值为每层之和dfs(root, 0);int ans = 0;for(int i = 0; i < sum.size(); i++){if(sum.get(i) > sum.get(ans)){ans = i;}}return ans + 1;}// 深度优先private void dfs(TreeNode node, int level){if(level == sum.size()){// 为什么直接加,每一层的第一个,每一个新的深度,因为之前没有所以直接add加,之后有了这个level,就可以get(level)+val了sum.add(node.val);}else{// 根据level,取出之前的层数和,然后加上当前节点值,组合成每层之和sum.set(level, sum.get(level) + node.val);}if(node.left != null){dfs(node.left, level + 1);}if(node.right != null){dfs(node.right, level + 1);}}
}