携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
一、题目
LeetCode 最大层内元素和
给你一个二叉树的根节点 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
提示:
树中的节点数在 [1, 104]范围内
-105 <= Node.val <= 105
二、题解
给定有一颗二叉树,从根节点往下按层级统计每一层的节点元素值之和,返回节点元素和最大并且层级最小的那一层。
方法一
需要按层计算层节点元素和,那么可以通过深度优先搜索dfs来遍历二叉树,首先需要dfs递归遍历二叉树的所有元素节点,同时遍历过程中需要记得当前的层级,这里用level表示当前的层级号,初始的从0开始即根节点。然后遍历过程中需要一个数组统计每一层的元素之和。如果是新的一层就直接记录当前节点值,否则就累加上之前层的元素和。然后继续遍历左右子树的节点。最后遍历结束时数组中记录的每一层的节点元素之和,只需要遍历数组,计算元素和最大的那一层的层级号即可,最后返回的层级号需要加一。
方法二 同样的按层统计元素和,也可以使用广度优先搜索bfs来遍历二叉树,首先bfs遍历过程中需要一个队列来辅助遍历,队列中记录每一层的节点,然后统计层节点和,最后返回最大层节点和的层级即可。
三、代码
方法一 Java代码
class Solution {
private List<Integer> levelSum = new ArrayList<Integer>();
public int maxLevelSum(TreeNode root) {
dfs(root, 0);
int ans = 0;
for (int i = 0; i < levelSum.size(); ++i) {
if (levelSum.get(i) > levelSum.get(ans)) {
ans = i;
}
}
return ans + 1;
}
private void dfs(TreeNode node, int level) {
if (node == null) {
return;
}
if (level == levelSum.size()) {
levelSum.add(node.val);
} else {
levelSum.set(level, levelSum.get(level) + node.val);
}
dfs(node.left, level + 1);
dfs(node.right, level + 1);
}
}
时间复杂度:O(n),递归遍历一次二叉树的节点。
空间复杂度:O(n),需要一个数组记录以及递归消耗栈空间。
方法二 Java代码
class Solution {
public int maxLevelSum(TreeNode root) {
int target = 1;
int curLevel = 0;
int ans = Integer.MIN_VALUE;
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int curSize = queue.size();
int curAns = 0;
curLevel++;
for (int i = 0; i < curSize; i++) {
TreeNode curNode = queue.poll();
curAns += curNode.val;
if (curNode.left != null) {
queue.offer(curNode.left);
}
if (curNode.right != null) {
queue.offer(curNode.right);
}
}
if (curAns > ans) {
target = curLevel;
ans = curAns;
}
}
return target;
}
}
时间复杂度:O(n),递归遍历一次二叉树的节点。
空间复杂度:O(n),需要一个队列辅助遍历。