题目简介
实现代码:
/**
* @ClassName 最大层内元素和
* @since: 2023/8/20 09:16
* @auth: kirito
* @description:
* 给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。
*
* 请返回层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。
*
* 在初始化变量 max 时,直接使用了 root.val,
* 但是在判断 root 是否为空之前,会导致空指针异常。
* 应该将初始化 max 的代码放在判断 root 是否为空之后。
*
*
**/
public class 最大层内元素和 {
public static int maxLevelSum(TreeNode root) {
// * 在初始化变量 max 时,直接使用了 root.val,
// * 但是在判断 root 是否为空之前,会导致空指针异常。
// * 应该将初始化 max 的代码放在判断 root 是否为空之后。
if (root == null) {
return 0;
}
int max = root.val; // 保存最大层级和的值
int depth = 1; // 当前层级
int ans = 1; // 最大层级和所在的层级
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
// 在内层循环中,使用 queue.size() 作为循环的终止条件,
// 但是在循环过程中,队列的大小是会动态变化的,因此不能使用固定的大小。
// 应该在每一层开始之前,先将当前层的节点个数保存下来,
// 然后在循环中使用这个固定的节点个数作为终止条件。
int size = queue.size(); // 当前层级的节点个数
int sum = 0; // 当前层级的节点值之和
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
sum += node.val;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
if (sum > max) {
max = sum; // 更新最大层级和
ans = depth; // 更新最大层级和所在的层级
}
depth++; // 进入下一层级
}
return ans; // 返回最大层级和所在的层级
}
思路:
层序遍历,可以利用队列的先进先出的机制完成。
易错:
1.
// * 在初始化变量 max 时,直接使用了 root.val, // * 但是在判断 root 是否为空之前,会导致空指针异常。 // * 应该将初始化 max 的代码放在判断 root 是否为空之后。
2.
在队列非空情况下循环遍历每一层节点时,需要定义size变量存储当前层级的节点个数,不能直接用queue.size(),因为在利用队列特性的时候,我们是在循环中间进行了入队操作,会导致队列的大小动态变化,导致每次并不是遍历的每一层,而是多层,导致不能实现我们想要的效果,需要注意。。。
// 在内层循环中,使用 queue.size() 作为循环的终止条件, // 但是在循环过程中,队列的大小是会动态变化的,因此不能使用固定的大小。 // 应该在每一层开始之前,先将当前层的节点个数保存下来, // 然后在循环中使用这个固定的节点个数作为终止条件。
3.
另外需要注意的一个点,题目要求返回的是最大值中最小的层数,我们需要记录一个depth来记录树的深度,ans记录之前的最大值的层数,如果符合条件,depth赋值给ans==》ans表示目前最大数的深度,直到queue为空,返回ans即可,