文章目录
- 题目
- 标题和出处
- 难度
- 题目描述
- 要求
- 示例
- 数据范围
- 解法一
- 思路和算法
- 代码
- 复杂度分析
- 解法二
- 思路和算法
- 代码
- 复杂度分析
题目
标题和出处
标题:最大层内元素和
出处:1161. 最大层内元素和
难度
4 级
题目描述
要求
给定一个二叉树的根结点 root \texttt{root} root。设根结点位于二叉树的第 1 \texttt{1} 1 层,而根结点的子结点位于第 2 \texttt{2} 2 层,以此类推。
请返回最小的 x \texttt{x} x,使得第 x \texttt{x} x 层的结点值之和最大。
示例
示例 1:
输入:
root
=
[1,7,0,7,-8,null,null]
\texttt{root = [1,7,0,7,-8,null,null]}
root = [1,7,0,7,-8,null,null]
输出:
2
\texttt{2}
2
解释:
第
1
\texttt{1}
1 层各元素之和为
1
\texttt{1}
1。
第
2
\texttt{2}
2 层各元素之和为
7
+
0
=
7
\texttt{7 + 0 = 7}
7 + 0 = 7。
第
3
\texttt{3}
3 层各元素之和为
7
+
(-8)
=
-1
\texttt{7 + (-8) = -1}
7 + (-8) = -1。
所以我们返回元素之和最大的层,为第
2
\texttt{2}
2 层。
示例 2:
输入:
root
=
[989,null,10250,98693,-89388,null,null,null,-32127]
\texttt{root = [989,null,10250,98693,-89388,null,null,null,-32127]}
root = [989,null,10250,98693,-89388,null,null,null,-32127]
输出:
2
\texttt{2}
2
数据范围
- 树中结点数目在范围 [1, 10 4 ] \texttt{[1, 10}^\texttt{4}\texttt{]} [1, 104] 内
- -10 5 ≤ Node.val ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{Node.val} \le \texttt{10}^\texttt{5} -105≤Node.val≤105
解法一
思路和算法
为了得到二叉树中结点值之和最大的层,需要计算二叉树的每一层的结点值之和。可以使用层序遍历实现。
从根结点开始依次遍历每一层的结点,在层序遍历的过程中需要区分不同结点所在的层,确保每一轮访问的结点为同一层的全部结点。遍历每一层结点之前首先得到当前层的结点数,即可确保每一轮访问的结点为同一层的全部结点。
对于每一层结点,遍历过程中可以得到当前层的结点值总和。
由于二叉树的第 1 1 1 层只有根结点,因此第 1 1 1 层的层内元素和即为根结点值。将最大层内元素和初始化为根结点值,将结点值之和最大的层初始化为第 1 1 1 层。遍历过程中,如果第 level \textit{level} level 层的结点值之和严格大于最大层内元素和,则将最大层内元素和更新为第 level \textit{level} level 层的结点值之和,将结点值之和最大的层更新为 level \textit{level} level。如果有多个层的结点值之和都是最大,则上述做法可以确保返回的层编号为其中最小的层编号。
代码
class Solution {
public int maxLevelSum(TreeNode root) {
int maxSum = root.val;
int maxLevel = 1;
int level = 0;
Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
level++;
int sum = 0;
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
sum += node.val;
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
if (sum > maxSum) {
maxSum = sum;
maxLevel = level;
}
}
return maxLevel;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是队列空间,队列内元素个数不超过 n n n。
解法二
思路和算法
也可以使用深度优先搜索得到二叉树中结点值之和最大的层。从根结点开始遍历二叉树,遍历过程中需要维护二叉树每一层的结点值总和。对于每个非空结点,都可以得到其结点值与所在层,将所在层的结点值总和加上当前结点值,然后对当前结点的非空子结点继续遍历。
遍历结束之后得到二叉树每一层的结点值总和,此时即可得到结点值之和最大的层。
代码
class Solution {
int totalLevels = 0;
List<Integer> sums = new ArrayList<Integer>() {{
add(0);
}};
public int maxLevelSum(TreeNode root) {
dfs(root, 1);
int maxSum = root.val;
int maxLevel = 1;
for (int i = 2; i <= totalLevels; i++) {
int sum = sums.get(i);
if (sum > maxSum) {
maxSum = sum;
maxLevel = i;
}
}
return maxLevel;
}
public void dfs(TreeNode node, int level) {
totalLevels = Math.max(totalLevels, level);
if (level < sums.size()) {
sums.set(level, sums.get(level) + node.val);
} else {
sums.add(node.val);
}
if (node.left != null) {
dfs(node.left, level + 1);
}
if (node.right != null) {
dfs(node.right, level + 1);
}
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间以及存储每一层的结点值总和的列表,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)。